zoukankan      html  css  js  c++  java
  • 并发与多版本:update重启动问题

    以下演示重启动问题,请注意 before触发器和after触发器的行为区别,因为before触发器会触发两次而导致重启动问题,因此使用after触发器更加高效,应该尽量避免在所有触发器中使用自治事务

    -------演示before触发器导致的查询重启动问题

    1、创建测试表

    create table test4(x number, y number);

    insert  into test4 values (1,4);

    commit;

    2、创建before触发器

    create or replace trigger t4
    before update on test4 for each row
    begin
     dbms_output.put_line('old.y-->'||:old.y);
     dbms_output.put_line('new.y-->'||:new.y);
    end;

    3、执行更新

    session 1:

    SQL> select vm.*,to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from v$mystat vm where rownum =1;

           SID STATISTIC#      VALUE TO_CHAR(SYSDATE,'YYYY-MM-DDHH2

    ---------- ---------- ---------- ------------------------------

            13          0          0 2016-04-28 10:05:44

    SQL> update test4 set y=y+1 where x=1;

    old.y-->4

    new.y-->5

    1 row updated

    ---注:此时不提交

    session 2:

    SQL> select vm.*,to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from v$mystat vm where rownum =1;

           SID STATISTIC#      VALUE TO_CHAR(SYSDATE,'YYYY-MM-DDHH2

    ---------- ---------- ---------- ------------------------------

            73          0          0 2016-04-28 10:07:31

    SQL> update test4 set y=y+1 where x=1;

    ---此时session2 会被session阻塞,一直等待session1提交或回滚;

    返回至session1,执行提交;

    SQL> commit;

    Commit complete

    ---此时切换到session2查看,发现before 触发器打印的信息有点奇怪,这个现象就是重启动

    old.y-->4

    new.y-->5

    old.y-->5

    new.y-->6

    1 row updated

    4、修改before触发器,不使用:old和:new,再次重复上述1~3过程,发现不在出现重启动现象

    create or replace trigger t4
    before update on test4 for each row
    begin
     dbms_output.put_line('this is before trigger');
    end;

    session1:

    SQL> update test4 set y=y+1 where x=1;

    this is a before trigger

    1 row updated

    session2:

    SQL> update test4 set y=y+1 where x=1;

    this is a before trigger

    1 row updated (此时被session1阻塞)

    返回session1执行提交:

    SQL> commit;

    Commit complete

    返回session2查看结果:

    SQL> update test4 set y=y+1 where x=1;

    this is a before trigger

    1 row updated

    -------演示after触发器不会导致查询重启动

    1、先drop before 触发器:

    SQL> drop trigger t4;

    Trigger dropped

    2、创建after触发器:

    create or replacetrigger t5

    after update on test4 for each row

    begin

    dbms_output.put_line( 'old.y-->'||:old.y);

    dbms_output.put_line('new.y-->'||:new.y);

    end;

    3、执行更新

    session1:

    SQL> update test4 set y=y+1 where x=1;

    old.y-->7

    new.y-->8

    1 row updated

    session2:

    SQL> update test4 set y=y+1 where x=1; ---由于session1未提交,session2此时被阻塞

    返回session1,执行提交:

    SQL> commit;

    Commit complete

    返回session2 查看结果:

    old.y-->8

    new.y-->9

    1 row updated

    注:此时并没有输出4行,而只是输出2行

    ----以上信息来自tom书籍

  • 相关阅读:
    应用js改变问章字体大小
    在北京实习的日子
    php算法
    SQL Server 查询处理中的各个阶段(SQL执行顺序)
    130 个你需要了解的 vim 命令
    分享一个检测用户是否用手机(Mobile)访问网站的 PHP 类
    使用apache自带日志分割模块rotatelogs,分割日志
    centos下lvs配置
    分享codeigniter框架,在zend studio 环境下的代码提示
    vi 常用命令
  • 原文地址:https://www.cnblogs.com/pompeii2008/p/5441715.html
Copyright © 2011-2022 走看看