23hibernate_pessimistic_locking
悲观锁
悲观锁的实现,通常依赖于数据库机制,在整个过程中将数据锁定,其它任何用户都不能读取或修改
ExportDB:
create table t_inventory (itemNo integer not null auto_increment, itemName varchar(255), quantity integer, primary key (itemNo))
public class Inventory {
private int itemNo;
private String itemName;
private int quantity;
<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>
package com.bjsxt.hibernate;
import org.hibernate.Session;
public class InitData {
public static void main(String[] args) {
Session session = null;
try {
session = HibernateUtils.getSession();
session.beginTransaction();
Inventory inv = new Inventory();
inv.setItemNo(1001);
inv.setItemName("脑白金");
inv.setQuantity(1000);
session.save(inv);
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUtils.closeSession(session);
}
}
}
Hibernate: insert into t_inventory (itemName, quantity) values (?, ?)
mysql> select * from t_inventory;
+--------+----------+----------+
| itemNo | itemName | quantity |
+--------+----------+----------+
| 1 | 脑白金 | 1000 |
+--------+----------+----------+
1 row in set (0.00 sec)
TestLoad1:
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);//1000
session.update(inv);
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUtils.closeSession(session);
}
}
Hibernate: select inventory0_.itemNo as itemNo0_0_, inventory0_.itemName as itemName0_0_, inventory0_.quantity as quantity0_0_ from t_inventory inventory0_ where inventory0_.itemNo=? for update
TestLoad2:
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);
}
}
mysql> select * from t_inventory;
+--------+----------+----------+
| itemNo | itemName | quantity |
+--------+----------+----------+
| 1 | 脑白金 | 1000 |
+--------+----------+----------+
1 row in set (0.00 sec)
TestLoad1:
Hibernate: select inventory0_.itemNo as itemNo0_0_, inventory0_.itemName as itemName0_0_, inventory0_.quantity as quantity0_0_ from t_inventory inventory0_ where inventory0_.itemNo=? for update
TestLoad2:等待第一个事务的提交
Hibernate: select inventory0_.itemNo as itemNo0_0_, inventory0_.itemName as itemName0_0_, inventory0_.quantity as quantity0_0_ from t_inventory inventory0_ where inventory0_.itemNo=? for update
quantity=600
Hibernate: update t_inventory set itemName=?, quantity=? where itemNo=?
Hibernate: select inventory0_.itemNo as itemNo0_0_, inventory0_.itemName as itemName0_0_, inventory0_.quantity as quantity0_0_ from t_inventory inventory0_ where inventory0_.itemNo=? for update
mysql> select * from t_inventory;
+--------+----------+----------+
| itemNo | itemName | quantity |
+--------+----------+----------+
| 1 | 脑白金 | 600 |
+--------+----------+----------+
1 row in set (0.00 sec)
悲观锁的实现,通常依赖于数据库机制,在整个过程中将数据锁定,其它任何用户都不能读取或修改
ExportDB:
create table t_inventory (itemNo integer not null auto_increment, itemName varchar(255), quantity integer, primary key (itemNo))
public class Inventory {
private int itemNo;
private String itemName;
private int quantity;
<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>
package com.bjsxt.hibernate;
import org.hibernate.Session;
public class InitData {
public static void main(String[] args) {
Session session = null;
try {
session = HibernateUtils.getSession();
session.beginTransaction();
Inventory inv = new Inventory();
inv.setItemNo(1001);
inv.setItemName("脑白金");
inv.setQuantity(1000);
session.save(inv);
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUtils.closeSession(session);
}
}
}
Hibernate: insert into t_inventory (itemName, quantity) values (?, ?)
mysql> select * from t_inventory;
+--------+----------+----------+
| itemNo | itemName | quantity |
+--------+----------+----------+
| 1 | 脑白金 | 1000 |
+--------+----------+----------+
1 row in set (0.00 sec)
TestLoad1:
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);//1000
session.update(inv);
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUtils.closeSession(session);
}
}
Hibernate: select inventory0_.itemNo as itemNo0_0_, inventory0_.itemName as itemName0_0_, inventory0_.quantity as quantity0_0_ from t_inventory inventory0_ where inventory0_.itemNo=? for update
TestLoad2:
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);
}
}
mysql> select * from t_inventory;
+--------+----------+----------+
| itemNo | itemName | quantity |
+--------+----------+----------+
| 1 | 脑白金 | 1000 |
+--------+----------+----------+
1 row in set (0.00 sec)
TestLoad1:
Hibernate: select inventory0_.itemNo as itemNo0_0_, inventory0_.itemName as itemName0_0_, inventory0_.quantity as quantity0_0_ from t_inventory inventory0_ where inventory0_.itemNo=? for update
TestLoad2:等待第一个事务的提交
Hibernate: select inventory0_.itemNo as itemNo0_0_, inventory0_.itemName as itemName0_0_, inventory0_.quantity as quantity0_0_ from t_inventory inventory0_ where inventory0_.itemNo=? for update
quantity=600
Hibernate: update t_inventory set itemName=?, quantity=? where itemNo=?
Hibernate: select inventory0_.itemNo as itemNo0_0_, inventory0_.itemName as itemName0_0_, inventory0_.quantity as quantity0_0_ from t_inventory inventory0_ where inventory0_.itemNo=? for update
mysql> select * from t_inventory;
+--------+----------+----------+
| itemNo | itemName | quantity |
+--------+----------+----------+
| 1 | 脑白金 | 600 |
+--------+----------+----------+
1 row in set (0.00 sec)