1.悲观锁定:
在多个客户端可能读取同一笔数据或同时更新一笔数据的情况下,必须要有访问控制的手段,防止同一个数据被修改而造成混乱,最简单的手段就是对资料进行锁定,在自己进行资料读取或更新等动作时,锁定其他客户端不能对同一笔资料进行任何的动作。
悲观锁定(Pessimistic Locking)一如其名称所示,悲观的认定每次资料存取时,其它的客户端也会存取同一笔资料,因此对该笔资料进行锁定,直到自己操作完成後解除锁定。
悲观锁定通常透过系统或资料库本身的功能来实现,依赖系统或资料库本身提供的锁定机制,Hibernate即是如此,可以利用Query或Criteria的setLockMode()方法来设定要锁定的表或列(Row)及其锁定模式,可设定的锁定模式有以下的几个:
LockMode.UPGRADE:利用资料库的for update子句进行锁定。
LockMode.UPGRADE_NOWAIT:使用for update nowait子句进行锁定,在Oracle资料库中使用。
一个设定锁定的例子如下:
Session session = sessionFactory.openSession();
Query query = session.createQuery("from User user");
query.setLockMode("user", LockMode.UPGRADE);
List users = query.list();
...
session.close();这个程式片段会使用以下的SQL进行查询:
Hibernate: select user0_.id as id, user0_.name as name0_, user0_.age as age0_
from user user0_ for update也可以在使用Session的load()或是lock()时指定锁定模式以进行锁定。
另外还有三种加锁模式Hibernate内部自动对资料进行锁定,与资料库无关:
LockMode.WRITE:在insert或update时进行锁定,Hibernate会在save()方法时自动获得锁定。
LockMode.READ:在读取记录时Hibernate会自动获得锁定。
LockMode.NONE:没有锁定。
如果资料库不支援所指定的锁定模式,Hibernate会选择一个合适的锁定替换,而不是丢出一个例外。