Hibernate的悲观锁与乐观锁
Hibernate里面的锁:
NONE:无锁,全部锁操作最后都会变成这个锁策略;
READ:读锁,即共享锁,允许多个事务共同读同一部分数据,进行读操作室自动加上读锁;
WRITE:写锁,写操作时对数据进行绑定,进行写操作时自动加上写锁;
UPGRADE:悲观锁,会加上select...for update,为数据加上行锁(文档上写了是行锁);
UPGRADE_NOWAIT: 对于ORACLE数据库有用的锁策略;
Hibernate的悲观锁与乐观锁用于解决并发访问数据库的问题;
悲观锁就是认为并发访问时,数据会被改,出现错误,就对数据进行锁定,这样能避免并发产生的五种问题,但会严重影响并发的性能,依赖数据库的锁;
乐观锁就是认为并访问时不会出现那些问题,允许并发的条件宽松多了,但是会采用版本号控制的策略来避免并发时的覆盖更新和丢失更新,不依赖数据库的锁;
设置悲观锁的三种方式(写锁是只允许被Hibernate内部调用的,通常只显式设置悲观锁):
session.load()
session.lock()
query.setLockOption()
设置乐观锁:
给实体加上属性,属性用@Version修饰,再加上相应的getter和setter方法,如下即可:
@Version @Column(name = "version_num") private Integer versionNum;
乐观锁的原理,每一次修改实体,实体的versionNum就会加1,修改的时候,sql语句上就会有“where version_num = sql里的version_num”,如果数据库里的version_num比sql里的version_num要大,说明对应的记录已经被修改过了,这时候,
Hibernate就会抛出异常,通过这种方式,能避免且只能避免覆盖更新(且注意,hql和sql都要手动加上乐观锁控制,不然就失效);
注意,使用乐观锁,只会在update()等方法的时候自动添加乐观锁,hql和sql方式的,不会自动添加乐观锁;
注意,使用乐观锁,使用hql和sql方式时需要手动加上版本号的限制,不然就失效;使用悲观锁同理。
浙公网安备 33010602011771号