DML事务锁定机制

DML事务锁定机制

          能够保证当某个用户正在更新表里的一行数据时, 其他用户不能同时更新相同的数据行, 而且也不能删除或修改被更新的表。

          行级锁(TX锁)

          UPDATE EMPLOYEE SET LAST_NAME='xkj' WHERE EXPLOYEE_ID=100 ;

          1. ORACLE对该SQL语句进行解析, 找到EXPLOYEE_ID为100的记录所在的数据块(假设为58号数据块), 并找到一个可用的undo数据块, 将LAST_NAME列上被更新前的旧值放入该undo数据块。

          2. 在58号数据块的头部分配一个ITL槽, 在该槽里存放当前的事务ID、SCN号、所使用的undo数据块的地址, 以及未提交的标记等信息。

          3. 在58号数据块中, 找到被更新的数据行, 在数据行头部设置一个锁定标记, 并在头部记录当前事务所使用ITL槽号, 做完这些工作。

          4. 控制权交给用户, 该锁定说明当前用户在被修改的数据行上已经添加了X锁。

          如果这时, 另一个用户B也对EXPLOYEE_ID为100的记录进行修改, 则其过程和上面描述一样, 只不过B在对数据行的头部设置锁定标记的时候, 发现该数据行头部已经有一个锁定标记了, 说明该记录已经添加了X锁, 于是用户B必须等待, 等待X锁被释放。

          锁定一条记录, 并不影响其他用户对该记录的读取, 比如:

          如果用户发出一条SQL语句,检索EXPLOYEE_ID为100的记录信息, 这时服务器进程发现被检索的记录有锁定标记, 说明该记录已经被其他用户修改了, 但是还没有提交。于是根据数据行头部记录到ITL槽的号码, 在数据块头部找到ITL槽, 并根据其中记录的undo数据块的地址, 找到该undo数据块, 将其中所保存的改变前的旧值取出来, 并构建CR(consistent read读一致性)块, 根据CR块的内容, 将用户所需要的信息进行返回。

          对于ORACLE来说, 行级锁只有X锁定模式, 没有S锁定模式, 更新数据行, 只是锁定被更新的行。(这里与ORACLE锁文章里的X锁不允许其他事务读取和修改矛盾???因为排他锁不允许其他事务读取和修改, 但是上面的例子却明显的被其他的事务读取了。这是个疑问???)

          表级锁(TM锁)

          用户A已经发出了更新EXPLOYEE_ID为100的记录的SQL语句。当A还没有提交之前, 另外一个用户D发出下面的语句:

          DROP TABLE EMPLOYEE;

          由于用户A还没有提交所做的事务, 因此该事务还没有结束, 其他用户还不能删除该表, 否则A所发出的事务就无法正常结束。为了阻止这时用户D的删除操作, 我们能够想到的最直观的方法就是, 在执行删除表的命令之前, 先依次检查EMPLOYEE表里的每一条记录, 查看每一条数据行的头部是否存在锁定标记, 如果是, 则说明当前正在有事务更新该表, 删除表的操作必须等待。

          显然,  这种方式会引起很大的性能问题, ORACLE不会采用这种方式。实际上, 当我们在对EMPLOYEE表的数据进行更新时, 不仅会在数据行的头部记录行级锁, 而且还会在表的级别上添加一个表级锁。那么当D用户要删除表时, 发现EMPLOYEE表上具有一个表级锁, 于是等待。

          通过这种在表级别上添加锁定的方式, 我们就能够比较容易高效的(因为不需要扫描表里的每一条记录来判断在表上是否有DML事务)对锁定进行管理了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值