1.悲观锁
悲观锁不是hibernate的锁,这是数据库的update锁。Select * from item for update。Hibernate就是用的这种机制,在查询上上锁。
public class Item {
private Integer itemId;
private String itemName;
private Integer stock;
<hibernate-mapping package="com.zy.hiber.model">
<!-- 字表映射,需要把父类的映射设置成抽象的(不会产生父表)
abstract="true"
-->
<class name="Item" table="t_item" >
<id name="itemId" column="item_id">
<generator class="native"></generator>
</id>
<property name="itemName" column="item_name"></property>
<property name="stock"></property>
</class>
</hibernate-mapping>
保存:
@Test
public void save(){
Session session = HibernateUtils.getSession();
Transaction tx = session.beginTransaction();
try {
Item item = new Item();
item.setItemName("ipad");
item.setStock(100);
session.save(item);
tx.commit();
} catch (Exception e) {
e.printStackTrace();
tx.rollback();
}finally{
HibernateUtils.closeResource(session);
}
}
查询:
@Test
public void query(){
Session session = HibernateUtils.getSession();
Transaction tx = session.beginTransaction();
try {
//使用悲观锁查询,如果一个请求在查询时,另一个请求被阻塞在外
Item item = (Item)session.load(Item.class, 1,LockOptions.UPGRADE);
item.setStock(item.getStock() - 2);
tx.commit();
} catch (Exception e) {
e.printStackTrace();
}finally{
HibernateUtils.closeResource(session);
}
}
2.乐观锁
悲观锁的性能比较低,因为查询也被锁住,我们乐观锁可以很好解决这个问题。
@Test
public void updateStock(){
Session session = HibernateUtils.getSession();
Transaction tx = session.beginTransaction();
try{
Item item = (Item) session.load(Item.class, 1);
item.setStock(item.getStock() - 2);
tx.commit();
} catch (Exception e) {
e.printStackTrace();
tx.rollback();
}finally{
HibernateUtils.closeResource(session);
}
}
Select * from t_item where item_id = 1001;
1001 iphone 100 1
Update t_item set t.stock = 100 – 2, t.version = t.version+ 1 where t.item_id = 1001 and t.version = 1
A买了版本+1是2,B买的时候发现版本是2,和自己的1不相等,就不能执行。B要重新发起请求,异常处理。
这里强调version属性
<!-- 乐观锁的版本 -->
<version name="version"></version>
<property name="anName" column="an_name"></property>
<property name="gender"></property>