|
在多個客戶端可能讀取同一筆數據或同時更新一筆數據的情況下,必須要有訪問控制的手段,防止數據被多個並行交易同時修改而造成混亂,最簡單的手段就是對資料進行鎖
定,在自己進行資料讀取或更新等動作時,鎖定其他客戶端不能對同一筆資料進行任何的動作。 悲觀鎖定(Pessimistic Locking)一如其名稱所示,悲觀的認定每次資料存取時,其它的客戶端也會存取同一筆資料,因此對相關的資料進行鎖定,直到自己操作完成後解除鎖定。 對整個資料庫提高隔離層級,會使得並行存取時,整個應用程式的效能變差,我們想要的是,在適當的時機,再對資料庫進行鎖定,而後交易完成後解除鎖定。 可以利用Query或 Criteria的setLockMode()方法,來設定要鎖定的表或列(Row)及其鎖定模式,可設定的鎖定模式有以下的幾個:
一個設定鎖定的例子如下: Session
session = HibernateUtil.getSessionFactory().openSession();
Transaction tx = session.beginTransaction(); Query query = session.createQuery("from User user"); List users1 = query.list(); query.setLockMode("user", LockMode.UPGRADE); ... List users2 = query.list(); ... tx.commit(); session.close(); 如上設定,在這個交易期間,若有其它交易嘗試進行更新操作,則必須等待目前的交易結束,這個程式片段會使用以下的SQL進行查詢: Hibernate:
select user0_.id as id, user0_.name as name0_, user0_.age as age0_ from
user user0_ for
update
也可以在使用Session的lock()時指定鎖定模式以進行鎖定,例如: User user = (User) session.load(User.class, new Long(1));
session.lock(user, LockMode.UPGRADE); 或是簡化為: User user = (User) session.load(User.class, new Long(1), LockMode.UPGRADE);
另外還有三種LockMode:
如果資料庫不支援所指定的鎖定模式,Hibernate會選擇一個合適的鎖定替換,而不是丟出一個例外。 |