zoukankan      html  css  js  c++  java
  • 初步研究事务复制与订阅者触发器的运行先后顺序

    问题描述:
         transaction分为许多cmd。执行cmd之后也可能执行触发器。我想搞清楚transaction的cmd和订阅者触发器之间,cmd和cmd之间,transaction和transaction之间的运行先后顺序。
    Ps:这里不详细考察发布者、分发者,忽略具体的细节,只把结构简化为发布者——订阅者
     
    问题结论:
    1)
         对于一个transaction,
              对每个cmd,先上锁、执行cmd以更新Subscriber,然后等Subscriber触发的一连串事情都运行完后,才解锁、完成cmd;
              一个cmd完成后,才执行下一个cmd,即线性执行;
         
         对每个transaction,
              一个transaction宣告完成后,才执行下一个transaction,即线性执行
         
     
     
     
    探究使用的工具:
         sys.dm_tran_locks,复制监视器,优化器提示,触发器,WAITFOR
     
    问题探究:
    1)在一个transaction只有一个cmd的情况下,cmd和订阅者触发器的运行顺序
         Publisher的数据库为SourceExam,含有TestTrigger和TestTriggerDst两个表。没有触发器。
         Subscriber的数据库为DstExam,包含表TestTrigger和TestTriggerDst。表TestTrigger上包含触发器,且不开启NOT FOR REPLICATION选项,如下
              
     
       让发布者发布一个能在Subscriber处触动触发器的事务,然后运行如下语句
              
         会发现,发布者也在等待,其lastwaittype是WAITFOR,而且长期持有数据行上面的X锁和数据所在页面的IX锁。说明写事务还没全部完成。
         而此时用优化器提示with (nolock)来做SELECT操作,会发现,Subscriber表里的数据已经被更新。说明写事务内容本身已经做完了。
         等到WAITFOR的时间结束后,用上述查看锁的语句发现,写事务已经消失,说明写完成了。
         所以,我们大胆推断:
              对于单个cmd的处理,先上锁、执行对Subscriber的更新,然后等Subscriber产生的一连串事情都运行完后,才解锁、完成。
     
     
    2)在一个transaction有多个cmd的情况下,cmd和cmd之间的运行顺序
         Subscriber的TestTrigger表上的触发器改为如下
              
         同时,Publisher也设置一个触发器,内容为更改TestTriggerDst的数据。然后,发布一个能激发Publisher和Subscriber触发器的事务。这样,复制监视器里会显示:
                        
         然后可以看到,这回事务发布失败,可看到下述复制监视器里的消息。说明第一个cmd的删除执行之后,才执行第二个cmd
              
         这说明,第一个cmd的触发器要运行完毕,才能运行第二个cmd。可大胆猜想:
              第一个cmd宣告运行完后,第二个cmd才能运行
     
    另外,发生错误后,在Subscriber处发现TestTriggerDst依然存在。这是因为一个执行不成功的transaction会被回滚。
     
    3)在有多个transaction的情况下,transaction和transaction之间的运行顺序
         Subscriber的TestTrigger表上的触发器改为如下
              
         同时,利用GO语句或BEGIN TRANSACTION语句分别发送两个事务,事务A用于触动Subscriber的触发器,事务B则执行对TestTriggerDst的修改。然后,根据上述sys.dm_tran_locks的查询代码,可以判断第一个事务还在处理中;此时查询事务B修改的那个表,看事务B是否已执行。结果发现,在事务A未宣告完成期间,事务B不会得到执行,所以,我们大胆推断:
              第一个transaction宣告运行完毕后,第二个transaction才开始运行
                     
     
        
  • 相关阅读:
    在你想要放弃的那一刻,想想为什么当初坚持走到了这里
    将来的你一定会感谢现在奋斗的自己
    学习改变命运,拼搏成就未来
    springmvc的DispatcherServlet源码——doDispatch方法解析
    SpringMVC02 AbstractController And MultiActionController
    SpringMVC简介01
    NIO
    数据库的锁机制
    Spring和MyBatis环境整合
    事务的隔离级别和mysql事务隔离级别修改
  • 原文地址:https://www.cnblogs.com/linybo/p/12049903.html
Copyright © 2011-2022 走看看