It is not intended that users spend much time worrying about locking strategies. It's usually enough to specify an isolation level for the JDBC connections and then simply let the database do all the work. However, advanced users may sometimes wish to obtain exclusive pessimistic locks, or re-obtain locks at the start of a new transaction.
Hibernate总是使用数据库的锁定机制,从不在内存中锁定对象!
类LockMode
定义了Hibernate所需的不同的锁定级别。一个锁定 可以通过以下的机制来设置:
当Hibernate更新或者插入一行记录的时候,锁定级别自动设置为LockMode.WRITE
。
当用户显式的使用数据库支持的SQL格式SELECT ... FOR UPDATE
发送SQL的时候,锁定级别设置为LockMode.UPGRADE
当用户显式的使用Oracle数据库的SQL语句SELECT ... FOR UPDATE NOWAIT
的时候,锁定级别设置LockMode.UPGRADE_NOWAIT
当Hibernate在“可重复读”或者是“序列化”数据库隔离级别下读取数据的时候,锁定模式 自动设置为LockMode.READ
。这种模式也可以通过用户显式指定进行设置。
LockMode.NONE
代表无需锁定。在Transaction
结束时, 所有的对象都切换到该模式上来。与session相关联的对象通过调用update()
或者saveOrUpdate()
脱离该模式。
"显式的用户指定"可以通过以下几种方式之一来表示:
调用 Session.load()
的时候指定锁定模式(LockMode)
。
调用Session.lock()
。
调用Query.setLockMode()
。
如果在UPGRADE
或者UPGRADE_NOWAIT
锁定模式下调 用Session.load()
,并且要读取的对象尚未被session载入过,那么对象 通过SELECT ... FOR UPDATE
这样的SQL语句被载入。如果为一个对象调用 load()
方法时,该对象已经在另一个较少限制的锁定模式下被载入了,那 么Hibernate就对该对象调用lock()
方法。
如果指定的锁定模式是READ
, UPGRADE
或 UPGRADE_NOWAIT
,那么Session.lock()
就 执行版本号检查。(在UPGRADE
或者UPGRADE_NOWAIT
锁定模式下,执行SELECT ... FOR UPDATE
这样的SQL语句。)
如果数据库不支持用户设置的锁定模式,Hibernate将使用适当的替代模式(而不是扔出异常)。 这一点可以确保应用程序的可移植性。