博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Oracle的TX锁(行级锁、事务锁)
阅读量:7075 次
发布时间:2019-06-28

本文共 2957 字,大约阅读时间需要 9 分钟。

hot3.png

问题:如何使用事务? 
回答:一共有三步。 
1、先开启事务。 
•在Oracle中,事务是在上一次事务结束以后,数据“第一次”被修改时自动开启。 
•在java中,设置连接为手动提交模式开始。代码: 
connection.setAutoCommit(false)。
 
2、进行(多次)数据操作(增删改)…… 
3、结束事务: commit、rollback。 
问题:如何结束事务? 
回答: 
有两种方法: 
1、确认对数据的修改:提交,commit。 
2、撤消对数据的修改:回滚,rollback。 
另外,当Oracle系统或者PL/SQL脚本抛出异常,都会造成数据回滚。 
问题:什么是提交模式,与事务有什么关系? 
回答: 
提交模式有两种: 
自动提交:在每一次数据被修改以后,自动提交。这种模式下是无法支持事务的。 
手动提交:所有的数据修改都在内存中,当执行commit时才一起提交。只要有一条sql执行失败,则所有的sql自动回滚。只能在手动提交模式下才能使用事务。
 
3.1 Oracle的TX锁(行级锁、事务锁) 
许多对Oracle不太了解的技术人员可能会以为每一个TX锁代表一条被封锁的数据行,其实不然。TX的本义是Transaction(事务),当一个事务第一次执行数据更改(Insert、Update、Delete)或使用SELECT… FOR UPDATE语句进行查询时,它即获得一个TX(事务)锁,直至该事务结束(执行COMMIT或ROLLBACK操作)时,该锁才被释放。所以,一个TX锁,可以对应多个被该事务锁定的数据行(在我们用的时候多是启动一个事务,然后SELECT… FOR UPDATE NOWAIT)。
 
在Oracle的每行数据上,都有一个标志位来表示该行数据是否被锁定。Oracle不像DB2那样,建立一个链表来维护每一行被加锁的数据,这样就大大减小了行级锁的维护开销,也在很大程度上避免了类似DB2使用行级锁时经常发生的锁数量不够而进行锁升级的情况。数据行上的锁标志一旦被置位,就表明该行数据被加X锁,Oracle在数据行上没有S锁。 
3.2 TM锁(表级锁) 
3.2.1 意向锁的引出 
表是由行组成的,当我们向某个表加锁时,一方面需要检查该锁的申请是否与原有的表级锁相容;另一方面,还要检查该锁是否与表中的每一行上的锁相容。比如一个事务要在一个表上加S锁,如果表中的一行已被另外的事务加了X锁,那么该锁的申请也应被阻塞。如果表中的数据很多,逐行检查锁标志的开销将很大,系统的性能将会受到影响。为了解决这个问题,可以在表级引入新的锁类型来表示其所属行的加锁情况,这就引出了"意向锁"的概念。 
意向锁的含义是如果对一个结点加意向锁,则说明该结点的下层结点正在被加锁;对任一结点加锁时,必须先对它的上层结点加意向锁。如:对表中的任一行加锁时,必须先对它所在的表加意向锁,然后再对该行加锁。这样一来,事务对表加锁时,就不再需要检查表中每行记录的锁标志位了,系统效率得以大大提高。 
3.2.2 意向锁的类型 
由两种基本的锁类型(S锁、X锁),可以自然地派生出两种意向锁: 
意向共享锁(Intent Share Lock,简称IS锁):如果要对一个数据库对象加S锁,首先要对其上级结点加IS锁,表示它的后裔结点拟(意向)加S锁; 
意向排它锁(Intent Exclusive Lock,简称IX锁):如果要对一个数据库对象加X锁,首先要对其上级结点加IX锁,表示它的后裔结点拟(意向)加X锁。 
另外,基本的锁类型(S、X)与意向锁类型(IS、IX)之间还可以组合出新的锁类型,理论上可以组合出4种,即:S+IS,S+IX,X+IS,X+IX,但稍加分析不难看出,实际上只有S+IX有新的意义,其它三种组合都没有使锁的强度得到提高(即:S+IS=S,X+IS=X,X+IX=X,这里的"="指锁的强度相同)。所谓锁的强度是指对其它锁的排斥程度。 
这样我们又可以引入一种新的锁的类型: 
共享意向排它锁(Shared Intent Exclusive Lock,简称SIX锁):如果对一个数据库对象加SIX锁,表示对它加S锁,再加IX锁,即SIX=S+IX。例如:事务对某个表加SIX锁,则表示该事务要读整个表(所以要对该表加S锁),同时会更新个别行(所以要对该表加IX锁)。 
这样数据库对象上所加的锁类型就可能有5种:即S、X、IS、IX、SIX。 
具有意向锁的多粒度封锁方法中任意事务T要对一个数据库对象加锁,必须先对它的上层结点加意向锁。申请封锁时应按自上而下的次序进行;释放封锁时则应按自下而上的次序进行;具有意向锁的多粒度封锁方法提高了系统的并发度,减少了加锁和解锁的开销。 
3.3 Oracle的TM锁(表级锁) 
Oracle的DML锁(数据锁)正是采用了上面提到的多粒度封锁方法,其行级锁虽然只有一种(即X锁),但其TM锁(表级锁)类型共有5种,分别称为共享锁(S锁)、排它锁(X锁)、行级共享锁(RS锁)、行级排它锁(RX锁)、共享行级排它锁(SRX锁),与上面提到的S、X、IS、IX、SIX相对应。需要注意的是,由于Oracle在行级只提供X锁,所以与RS锁(通过SELECT … FOR UPDATE语句获得)对应的行级锁也是X锁(但是该行数据实际上还没有被修改),这与理论上的IS锁是有区别的。 锁的兼容性是指当一个应用程序在表(行)上加上某种锁后,其他应用程序是否能够在表(行)上加上相应的锁,如果能够加上,说明这两种锁是兼容的,否则说明这两种锁不兼容,不能对同一数据对象并发存取。 
下表为Oracle数据库TM锁的兼容矩阵(Y=Yes,表示兼容的请求; N=No,表示不兼容的请求;-表示没有加锁请求): 
表五:Oracle数据库TM锁的相容矩阵
一方面,当Oracle执行SELECT…FOR UPDATE、INSERT、UPDATE、DELETE等DML语句时,系统自动在所要操作的表上申请表级RS锁(SELECT…FOR UPDATE)或RX锁(INSERT、UPDATE、DELETE),当表级锁获得后,系统再自动申请TX锁,并将实际锁定的数据行的锁标志位置位(指向该TX锁);另一方面,程序或操作人员也可以通过LOCK TABLE语句来指定获得某种类型的TM锁。下表是笔者总结了Oracle中各SQL语句产生TM锁的情况: 
表六:Oracle数据库TM锁小结
 
我们可以看到,通常的DML操作(SELECT…FOR UPDATE、INSERT、UPDATE、DELETE),在表级获得的只是意向锁(RS或RX),其真正的封锁粒度还是在行级;另外,Oracle数据库的一个显著特点是,在缺省情况下,单纯地读数据(SELECT)并不加锁,Oracle通过回滚段(Rollback segment)来保证用户不读"脏"数据。这些都提高了系统的并发程度。 
 
由于意向锁及数据行上锁标志位的引入,减小了Oracle维护行级锁的开销,这些技术的应用使Oracle能够高效地处理高度并发的事务请求。

转载于:https://my.oschina.net/swearyd7/blog/167829

你可能感兴趣的文章
md test
查看>>
解决 Nginx + PHP-FPM (Permission denied)报错的办法
查看>>
Cisco IPSec ××× 设计总结
查看>>
python excel 转 csv
查看>>
xmake 工程描述语法更新
查看>>
linux5.4 构建LAMP网站服务平台
查看>>
Cookie与Session的区别
查看>>
比传统事务快10倍?一张图读懂阿里云全局事务服务GTS
查看>>
FAQ_Zabbix:解决模板收集到的数据和真实数据有偏差
查看>>
有关游戏外挂的一些思考
查看>>
Bootstrap 介绍
查看>>
Python 的经典设计格言,格言来源于 Python 但不限于 Python
查看>>
python random模块
查看>>
数据流中的中位数(未)
查看>>
利用xss偷cookie教學
查看>>
CentOS 安装过程【图片】
查看>>
深入Hadoop节点部署的策略
查看>>
linux驱动编译常见错误记录
查看>>
Android设备路径及容量的读取
查看>>
Cocos2d-x3.0模版容器详解之三:cocos2d::Value
查看>>