HibernateOptimisticLockingFailureException

今天用 getHibernateTemplate().saveOrUpdateAll(list); 時報如下錯誤,

org.springframework.orm.hibernate3.HibernateOptimisticLockingFailureException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1; nested exception is org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
Caused by: org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1

查找原因發現是hibernate樂觀鎖出了問題,我的應用在由於頻繁調用數據庫,導致有時會不能批量插入數據,

這是主要的原因:The error occurs because at least 2 transactions are working on the same record(s). If a record is read by 2 transactions, and if the record is saved by one transaction first, and then by the second one, an optimistic locking exception is thrown in the second transaction, because the assumption that nobody else was going to modify the record, doesn't hold. (Optimistic locking = You are optimistic about the facts that nobody else is going to need the same record)

解決方法:

1) make sure (by design) that records that are going to be updated, are touched by only a single transaction at any given moment


2) instead of optimistic locking, use pessimistic locking (problem: reduces scalability, and added complexity in application)  用悲觀鎖
3) retry the transaction: make sure that no non-transactional state is kept between retries. 出異常後重試一下。

對hibernate的樂觀鎖和悲觀鎖小結一下:
悲觀鎖的實現依靠數據庫提供的鎖機制(只有數據庫層提供的鎖機制才能真正的保證數據訪問的排他性),這樣就會大大增加
數據庫性能的開銷。
樂觀鎖大多是基於數據版本實現,


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章