【1】樂觀鎖定(Optimistic locking)采用的版本策略有:先提交為主(First commit win)、后提交為主(Last commit win)、合并沖突更新(Merge cofilcting updates)
【2】樂觀鎖定采用的版本策略實際上和SVN的版本沖突解決方案是同樣的:采用其它人的(先提交的)、采用自己的(后提交的)、合并他人和自己的(合并沖突更新)
【3】Hibernate推薦采用“版本號來實現先提交為主”的樂觀鎖定模式。在數據庫中增加一個列version,每次讀取時連該列一起讀取,在更新的時候將此版本號和數據庫中的版本號進行比較,如果大于等于則可以更新,如果小于則拋出異常。
【4】Hibernate同時支持“檢查對象最后一次更新前的屬性實現先提交為主”的模式:它適用于數據庫不在本地,或者不能更改的情況。它通過比較當前對象的屬性和數據庫中對象的屬性,如果發現在讀出后有更改則拋出異常。
【5】Hibernate的樂觀鎖定必須在配置文件hibernate.cfg.xml中定義:<class name="xxx.xxx" table = "xxx" optimistic-lock="all/version" [dynamic-update="true"]>來設定。version表示使用版本號鎖定,all配合dynamic-update表示使用對象屬性檢查做為版本檢查依據
【6】悲觀鎖定(Pessimistic locking)會采用基于數據庫提供的鎖機制來進行鎖定。它會在物理層對行甚至表進行鎖定。使得應用的并發性變差。
【7】Hibernate支持通過Query或Criteria的setLockMode(XXX)方法來設定表或行的鎖定模式,其支持的模式如下:
※ LockMode.NONE 如果在Hibernate的緩存中存在指定對象,就直接返回該對象的引用;否則就通過Select語句到數據庫中加載該對象。這是默認值
※ LockMode.Read 不管Hibernate的緩存中是否存在指定對象,總是通過select語句到數據庫中加載該對象;如果映射文件中設置了版本元素,就執行版本檢查,比較緩存中的指定對象是否和數據庫中的版本一致。
※ LockMode.UPGRADE 不管Hibernate的緩存中是否存在指定對象,總是通過select語句到數據庫中加載該對象;如果映射文件中設置了版本元素,就執行版本檢查,比較緩存中的指定對象是否和數據庫中的版本一致。如果數據庫系統支持悲觀鎖就執行select ... for update語句,如果數據庫系統不支持悲觀鎖,就執行普通的select語句。
※ LockMode.UPGRADE_NOWAIT 和LockMode.UPGRADE具有同樣的功能。此外對于Oracle數據庫,執行select ... for update nowait語句
※ LockMode.WRITE 當Hibernate向數據庫保存或者更新一個對象時,會自動使用此模式。這種模式僅供Hibernate內部使用。
-------------------------------------------------------------
生活就像打牌,不是要抓一手好牌,而是要盡力打好一手爛牌。