DML的重启

DML重启,这是我今天学到的一个重要概念,总结下:

DML操作时,会用到2种读:一致读和当前读,一致读用于更新前去找DML需要操作那些数据,当前读用于更新到当前数据时,看数据的最新版本,如果当前读与一致读看到的数据

不一致的话,就会发生DML的重启。重启DML即将DML影响的数据全部回滚(只针对DML操作的数据,事务中的其他DML操作不会受影响),重新再进行一次同样的DML。

DML重启一般是检测不到的,不过可以用触发器来监测,确实有这种现象

1. 建表

CREATE TABLE t (x INT,y INT);

2.插入数据

INSERT INTO t (x,y) VALUES (1,1);

3.创建t表update前的触发器

CREATE OR REPLACE TRIGGER t_tr
BEFORE UPDATE ON t FOR EACH ROW
BEGIN
  dbms_output.put_line(
  'old.x = '||:old.x ||'old.y = '||:old.y);
  dbms_output.put_line(
  'new.x = '||:new.x ||'new.y = '||:new.y);
  END;

4.session1 开始update

UPDATE t SET x=x+1 WHERE x>0;

并不提交,看下output

old.x = 1old.y = 1
new.x = 2new.y = 1

5.session2开始同样的update

UPDATE t SET x=x+1 WHERE x>0;

此时session2被session1阻塞,session1 提交,来看下session2的output

old.x = 1old.y = 1
new.x = 2new.y = 1
old.x = 2old.y = 1
new.x = 3new.y = 1

这里可以清楚的看到触发器被触发了2次,原因就是第一次当前读(x=2),与一致读(x=1)不一致,造成了update操作的重启!!!

这里大家就要注意两个问题:

1. 如果你用类似上面的触发器来控制程序的话,可能会发生你意想不到的结果,例如我本想只触发一次,结果不知道为什么触发了多次;

2.执行大批量数据的DML操作时,可能前面已经更新了10W行了,到下一行更新时,当前读与一致读不一致,结果前面的10W行更新将会

全部回滚!!这也许可以解释,为什么明明应该很快的DML操作有时候需要几倍的时间


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值