悲观锁
在应用程序中显示地为数据资源加锁
.
悲观锁假定当前事务操纵数据资源时
,
肯定还会有其它事务同时访问该数据资源
,
为了避免当前事务的操作受到干扰
,
先锁定资源
.
尽管悲观锁能防止丢失更新和不可重复读这类并发问题
,
但会影响并发性能
.
乐观锁
假定当前事务操纵数据资源时
,
不会有其它事务同时访问该数据资源
,
因此完全依靠数据库的隔离级别来自动管理锁的工作
.
应用程序采用版本控制手段来避免可能出现的并发问题
.
LockMode
类表示的几种锁定模式
锁定模式
|
描述
|
LockMode.NONE
|
如果缓存中存在对象
,
直接返回该对象的引用
,
否则通过
select
语句到数据库中加载该对象
,
默认值
.
|
LockMode.READ
|
不管缓存中是否存在对象
,
总是通过
select
语句到数据库中加载该对象
,
如果映射文件中设置了版本元素
,
就执行版本检查
,
比较缓存中的对象是否和数据库中对象版本一致
|
LockMode.UPGRADE
|
不管缓存中是否存在对象
,
总是通过
select
语句到数据库中加载该对象
,
如果映射文件中设置了版本元素
,
就执行版本检查
,
比较缓存中的对象是否和数据库中对象的版本一致
,
如果数据库系统支持悲观锁
(
如
Oracle/MySQL),
就执行
select...for
update
语句
,
如果不支持
(
如
Sybase),
执行普通
select
语句
|
LockMode.UPGRADE_NOWAIT
|
和
LockMode.UPGRADE
具有同样功能
,
此外
,
对于
Oracle
等支持
update
nowait
的数据库
,
执行
select...for
update
nowait
语句
,nowait
表明如果执行该
select
语句的事务不能立即获得悲观锁
,
那么不会等待其它事务释放锁
,
而是立刻抛出锁定异常
|
LockMode.WRITE
|
保存对象时会自动使用这种锁定模式
,
仅供
Hibernate
内部使用
,
应用程序中不应该使用它
|
LockMode.FORCE
|
强制更新数据库中对象的版本属性
,
从而表明当前事务已经更新了这个对象
|
多个事务并发运行时的并发问题
第一类丢失更新
:
撤销一个事务时
,
把其它事务已提交的更新数据覆盖
.
第二类丢失更新
:
不可重复读中的特例
,
一个事务覆盖另一事务已提交的更新数据
.
脏读
:
一个事务读到另一事务未提交的更新数据
.
幻读
:
一个事务读到另一事务已提交的新插入的数据
.
不可重复读
:
一个事务读到另一个事物已提交的更新数据
.
锁的类型和兼容性
共享锁
l
加锁条件
:
当一个事务执行
select
语句时
,
数据库系统会为这个事务分配一把共享锁
,
锁定被查询的数据
.
l
解锁条件
:
数据被读取后
,
数据库系统立即解除共享锁
.
l
与其它锁的兼容性
:
如果数据资源上放置了共享锁
,
还能再放置共享锁和更新锁
.
l
并发性能
:
良好的并发性能
.
当多个事务读相同数据时
,
每个事务都会获得一把共享锁
,
可以同时读锁定的数据
.
独占锁
l
加锁条件
:
当一个事务执行
insert,update,delete
时
,
数据库系统会自动对
SQL
语句操纵的数据资源使用独占锁
.
如果该数据资源已经有其它锁存在时
,
无法对其再放置独占锁
.
l
解锁条件
:
独占锁一直到事务结束后才能被解除
.
l
与其它锁的兼容性
:
独占锁不能和其他锁兼容
,
如果数据资源已经加上了独占锁
,
就不能再放置其它锁
,
同样
,
如果已经有了其它锁
,
就不能放置独占锁
.
l
并发性能
:
并发性能较差
,
只允许有一个事务访问锁定的数据
,
如果其他事务也需要访问该数据
,
就必须等待
,
直到前一个事务结束
,
解除了独占锁
,
其它事务才能访问该数据
.
更新锁
l
加锁条件
:
当一个事务进行
update
操作时
,
数据库系统会先为事务分配一把更新锁
.
l
解锁条件
:
当读取数据完毕
,
执行更新操作时
,
会把更新锁升级为独占锁
.
l
与其它锁的兼容性
:
更新锁与共享锁兼容
,
即一个资源可以同时放置更新锁和共享锁
,
但是最多只能放置一把更新锁
,
这样
,
当多个事务更新相同的数据时
,
只有一个事务能获得更新锁
,
然后再把更新锁升级为独占锁
,
其它事务必须等到前一个事务结束后
,
才能获得更新锁
,
避免了死锁
.
l
并发性能
:
允许多个事务同时读锁定资源
,
但不允许其它事务修改它
.
各种隔离级别所能避免的并发问题
隔离级别
|
是否出现第一类丢失更新
|
是否出现第二类丢失更新
|
是否出现脏读
|
是否出现幻读
|
是否出现不可重复读
|
Serializable
串行化
|
否
|
否
|
否
|
否
|
否
|
RepeatableRead
可重复读
|
否
|
否
|
是
|
否
|
否
|
ReadCommited
读已提交数据
|
否
|
否
|
是
|
是
|
是
|
ReadUncommited
读未提交数据
|
否
|
是
|
是
|
是
|
是
|
分享到:
相关推荐
主要介绍了Hibernate悲观锁和乐观锁实例详解,分享了相关代码示例,小编觉得还是挺不错的,具有一定借鉴价值,需要的朋友可以参考下
内含hibernate3.2与修复java.lang.NoSuchMethodError: org.objectweb.asm.ClassWriter.(Z)V 的错误的cglib2.2
通过监控数据库实例的锁使用情况,活跃锁的个数、死锁等信息,调整锁个数...1) onstat -k 监控当前活跃锁的个数,参照此设置LOCKS、DEF_TABLE_LOCKMODE参数,避免锁粒度太大、锁个数太多,浪费内存资源,从而影响性能。
通过v$lock很容易鉴定出来:可以看到,LockMode为6.等待队列分析当发现系统中由于此类锁导致的等待而致使会话hung住时,可以通过以下过程来找到导致阻塞的会话、语句和对象。续上,在Session2中执行
当某个数据库用户在数据库中插入、更新、删除一个表的数据,或者增加一个表的主键时或者表的索引时,常常会出现ora-00054:resource busy and acquire with nowait specified这样的错误。 主要是因为有事务正在执行...
3.hibernate的配置文件(hibernate.cfg.xml)得存在 4.POJO.hbm.xml文件存在 5.hibernate的jar包以及数据库的驱动包存在 Hibernate的编程: 1.构建Configuration对象读取配置文件 2.读取映射文件 3.构建SessionFactory...
本文为大家分享了Android九宫格手势解锁的具体代码,供... LockMode lockMode = (LockMode) getIntent().getSerializableExtra(Config.INTENT_SECONDACTIVITY_KEY); //是否显示手势的方向箭头 lv_lock.setShow(false)
sqlalchemy 对于行级锁有两种实现方式,with_lockmode(self, mode): 和 with_for_update(self, read=False, nowait=False, of=None),前者在sqlalchemy 0.9.0 被废弃,用后者代替。所以我们使用with_for_update ! 看...