[转]Hibernate-悲观锁与乐观锁、Hibernate的锁定机制

[转]Hibernate----悲观锁与乐观锁、Hibernate的锁定机制
[转]Hibernate----悲观锁与乐观锁、Hibernate的锁定机制
出自:http://www.blogjava.net/pengpenglin/archive/2010/03/15/315444.html
【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内部使用。