举例:
初始化类:
package com.java.hibernate;
import org.hibernate.Session;
public class InitData {
public static void main(String[] args) {
Session session = null;
try {
session = HibernateUtils.getSession();
session.beginTransaction();
Inventory inventory = new Inventory();
inventory.setItemNo("1000");
inventory.setItemName("冬虫夏草");
inventory.setQuantity(10000);
session.save(inventory);
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
} finally {
HibernateUtils.closeSession(session);
}
}
}
悲观锁:正如其名所示,“悲观”地认为每次读取或者修改数据库中的数据时,其他事务也在并发访问相同的数据。因此悲观锁会对读取的数据进行锁定,这样其他事务必须等待当前事务访问并且释放锁后才能继续访问这些数据。悲观锁即使在读取数据时,其他事务不能访问。悲观锁能防止丢失更新和不重复读问题,但是降低了并发性。在hibernate中使用LockMode.UPGREAD或者LockMode.UPGREAD_NOWAIT模式表示使用悲观锁,这种悲观锁完全基于数据库的锁机制实现。
实体类:
package com.java.hibernate;
public class Inventory {
private String itemNo;
private String itemName;
private int quantity;
public String getItemNo() {
return itemNo;
}
public void setItemNo(String itemNo) {
this.itemNo = itemNo;
}
public String getItemName() {
return itemName;
}
public void setItemName(String itemName) {
this.itemName = itemName;
}
public int getQuantity() {
return quantity;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
}
映射文件:
<?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.java.hibernate.Inventory" table="t_inventory">
<id name="itemNo" type="string">
<generator class="assigned"></generator>
</id>
<property name="itemName"></property>
<property name="quantity" type="int"></property>
</class>
</hibernate-mapping>
测试类:
package com.java.hibernate;
import junit.framework.TestCase;
import org.hibernate.LockMode;
import org.hibernate.Session;
public class Test extends TestCase {
public void testUser1() {
Session session = null;
try {
session = HibernateUtils.getSession();
session.beginTransaction();
Inventory inv = (Inventory)session.load(Inventory.class, "1000", LockMode.UPGRADE);
System.out.println("user1-->itemNo=" + inv.getItemNo());
System.out.println("user1-->itemName=" + inv.getItemName());
System.out.println("user1-->quantity=" + inv.getQuantity());
inv.setQuantity(inv.getQuantity() - 2000);
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUtils.closeSession(session);
}
}
public void testUser2() {
Session session = null;
try {
session = HibernateUtils.getSession();
session.beginTransaction();
Inventory inv = (Inventory)session.load(Inventory.class, "1000", LockMode.UPGRADE);
System.out.println("user2-->itemNo=" + inv.getItemNo());
System.out.println("user2-->itemName=" + inv.getItemName());
System.out.println("user2-->quantity=" + inv.getQuantity());
inv.setQuantity(inv.getQuantity() - 2000);
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUtils.closeSession(session);
}
}
}
乐观锁:采取了比较温柔的加锁机制,它乐观地认为数据库中的数据很少发生同时操作的问题,并且大多通过数据的版本号(Version)比较机制实现。
实体类:
package com.java.hibernate;
public class Inventory {
private String itemNo;
private String itemName;
private int quantity;
private int version;
public String getItemNo() {
return itemNo;
}
public void setItemNo(String itemNo) {
this.itemNo = itemNo;
}
public String getItemName() {
return itemName;
}
public void setItemName(String itemName) {
this.itemName = itemName;
}
public int getQuantity() {
return quantity;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
public int getVersion() {
return version;
}
public void setVersion(int version) {
this.version = 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.java.hibernate.Inventory" table="t_inventory" optimistic-lock="version">
<id name="itemNo">
<generator class="assigned"></generator>
</id>
<version name="version"></version>
<property name="itemName"></property>
<property name="quantity" type="int"></property>
</class>
</hibernate-mapping>
测试类:
package com.java.hibernate;
import junit.framework.TestCase;
import org.hibernate.Session;
public class Test extends TestCase {
public void testUser1() {
Session session = null;
try {
session = HibernateUtils.getSession();
session.beginTransaction();
Inventory inv = (Inventory)session.load(Inventory.class, "1000");
System.out.println("user1-->itemNo=" + inv.getItemNo());
System.out.println("user1-->version=" + inv.getVersion());
System.out.println("user1-->itemName=" + inv.getItemName());
System.out.println("user1-->quantity=" + inv.getQuantity());
inv.setQuantity(inv.getQuantity() - 2000);
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUtils.closeSession(session);
}
}
public void testUser2() {
Session session = null;
try {
session = HibernateUtils.getSession();
session.beginTransaction();
Inventory inv = (Inventory)session.load(Inventory.class, "1000");
System.out.println("user2-->itemNo=" + inv.getItemNo());
System.out.println("user2-->version=" + inv.getVersion());
System.out.println("user2-->itemName=" + inv.getItemName());
System.out.println("user2-->quantity=" + inv.getQuantity());
inv.setQuantity(inv.getQuantity() - 2000);
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUtils.closeSession(session);
}
}
}