乐观锁
大多数基于数据版本记录机制(version)实现,一般是在数据库表中加入一个version字段
读取数据时将版本号一同读出,之后更新数据时版本号加一,如果提交数据时版本号小于或等于数据表中
的版本号,则认为数据是过期的,否则给予更新
优点:并发性比较好
T_inventory 1001 nao 1000- 800 0 - 1 |
用户1 itemNo = 1001 itemName= nao quantity=1000-200=800 version=0 |
用户2 itemNo = 1001 itemName= nao quantity=1000 – 200=800 version=0 |
private int itemNo;
private String itemName;
private int quantity;
private int version;
<class name="com.bjsxt.hibernate.Inventory" table="t_inventory" optimistic-lock="version">默认就是version
<id name="itemNo">
<generator class="native"/>
</id>
<version name="version"/>
<property name="itemName"/>
<property name="quantity"/>
</class>
Inventory inv = new Inventory();
inv.setItemNo(1001);
inv.setItemName("脑白金");
inv.setQuantity(1000);
session.save(inv);
初始化无需保存version
缺点:用户体验不好(录入了大量东西,但提交时被告知已经修改,这样不好)
还可以采用时间戳
对于遗留系统,可以挨个字段比较
悲观锁
悲观锁的实现,通常依赖于数据库机制,在整个过程中将数据锁定,其它任何用户都不能读取或修改(适合短事务)
T_inventory 1001 nao 1000- 800 |
用户1 itemNo = 1001 itemName= nao quantity=1000-200=800 |
用户2 itemNo = 1001 itemName= nao quantity=1000 – 200=800
|
这样会造成更新丢失:
悲观锁:会锁住记录,在一个用户修改完成前,其他用户不能读取和修改
session.load(class, id, LockMode)用这种方式
session.load(Inventory.class, 1, LockMode.UPRADE); 这样会生成select..for update语句
加悲观锁后在load时马上发sql语句
缺点:并发性不好