悲观锁
悲观锁的实现,通常依赖于数据库机制,在整个过程中将数据锁定,其它任何用户都不能读取或修改
(不支持lazy)
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.bjsxt.hibernate.Inventory" table="t_inventory">
<id name="itemNo">
<generator class="native"/>
</id>
<property name="itemName"/>
<property name="quantity"/>
</class>
</hibernate-mapping>
/* 第一个设置断点,在让第二个执行,可看到效果
*/
public void testLoad1() {
Session session = null;
try {
session = HibernateUtils.getSession();
session.beginTransaction();
Inventory inv = (Inventory)session.load(Inventory.class, 1, LockMode.UPGRADE);
System.out.println("itemName=" + inv.getItemName());
System.out.println("quantity=" + inv.getQuantity());
inv.setQuantity(inv.getQuantity() - 200);
session.update(inv);
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUtils.closeSession(session);
}
}
public void testLoad2() {
Session session = null;
try {
session = HibernateUtils.getSession();
session.beginTransaction();
Inventory inv = (Inventory)session.load(Inventory.class, 1, LockMode.UPGRADE);
System.out.println("itemName=" + inv.getItemName());
System.out.println("quantity=" + inv.getQuantity());
inv.setQuantity(inv.getQuantity() - 200);
session.update(inv);
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUtils.closeSession(session);
}
}
乐观锁
大多数基于数据版本记录机制(version)实现,一般是在数据库表中加入一个version字段
读取数据时将版本号一同读出,之后更新数据时版本号加一,如果提交数据时版本号小于或等于数据表中
的版本号,则认为数据是过期的,否则给予更新
(支持lazy)
public class Inventory {
private int itemNo;
private String itemName;
private int quantity;
private int version;
}
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.bjsxt.hibernate.Inventory" table="t_inventory" optimistic-lock="version">
<id name="itemNo">
<generator class="native"/>
</id>
<version name="version"/>
<property name="itemName"/>
<property name="quantity"/>
</class>
</hibernate-mapping>
public void testLoad1() {
Session session = null;
try {
session = HibernateUtils.getSession();
session.beginTransaction();
Inventory inv = (Inventory)session.load(Inventory.class, 1);
System.out.println("itemName=" + inv.getItemName());
System.out.println("version=" + inv.getVersion());
System.out.println("quantity=" + inv.getQuantity());
inv.setQuantity(inv.getQuantity() - 200);
session.update(inv);
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUtils.closeSession(session);
}
}
public void testLoad2() {
Session session = null;
try {
session = HibernateUtils.getSession();
session.beginTransaction();
Inventory inv = (Inventory)session.load(Inventory.class, 1);
System.out.println("itemName=" + inv.getItemName());
System.out.println("version=" + inv.getVersion());
System.out.println("quantity=" + inv.getQuantity());
inv.setQuantity(inv.getQuantity() - 200);
session.update(inv);
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUtils.closeSession(session);
}
}