Hibernate 樂觀鎖和悲觀鎖處理事物併發問題
阿新 • • 發佈:2018-11-12
一、5類事物併發問題
二、事物的隔離級別
三、處理第一類丟失更新和第二類丟失更新--使用鎖機制
資料庫的鎖機制:
在MYSQL中 ,為了避免第二類丟失更新出現,提供了悲觀鎖的機制;
SELECT XXX FROM XXX FOR UPDATE;
SELECT FOR UPDATE就是在資料上新增一個共享鎖的東西;
1,共享鎖允許其他普通的SELECT語句執行;
2,共享鎖排斥其他的SELECT FOR UPDATE;
3,共享鎖排斥INSERT DELETE等DML;
在hibernate中使用悲觀鎖:
1,session1.createQuery("").setLockOptions(LockOptions.UPGRADE);
2,Account a=(Account)session1.get(Account.class,1L,LockOptions.UPGRADE);
3,Account a=(Account)session1.load(Account.class,1L,LockOptions.UPGRADE);
注意,
使用悲觀鎖會在一定情況下降低系統的併發效能;
如果系統對資料安全的要求非常高,請使用悲觀鎖;
樂觀鎖:
在hibernate中使用樂觀鎖:
1,在物件中新增一個private int version屬性,最好把setter/getter設定為private;
2,在對映檔案中新增:
四、例子
@Setter @Getter public class Account implements Serializable { private Long id; private int vesion; private Double balance; }
配置檔案
<hibernate-mapping package="com.shenzhenair.day03.Transactions" > <class name="Account"> <id name="id" > <generator class="native"/> </id> <property name="vesion" /> <property name="balance" /> </class> </hibernate-mapping>
測試用例:
@Test
public void testTransaction(){
Session session1 = HibernateUtils.openSession();
session1.beginTransaction();
Session session2 = HibernateUtils.openSession();
session2.beginTransaction();
Account a = (Account) session1.get(Account.class,1L);
Account b = (Account) session2.get(Account.class,1L);
a.setBalance(a.getBalance() - 5000);
b.setBalance(b.getBalance() + 5000);
try {
session2.getTransaction().commit();
session1.getTransaction().commit();
} catch (HibernateException e) {
e.printStackTrace();
System.out.println("請稍後再進行操作!");
}
session2.close();
session1.close();
}