문제 설명 :
cmd를 다수로 거래. cmd를 실행 한 후도 트리거를 수행 할 수있다. 내가 거래 및 가입자 트리거 사이에 생각 트랜잭션 및 트랜잭션 사이의 순서를 실행, cmd를 cmd를 사이에 명확하고 cmd를.
시는 : - 가입자 여기 게시자, 배포자, 특정 세부 사항을 무시하고, 구조 만이 게시자로 단순화 자세히 검사하지
결론 :
1)
트랜잭션의 경우,
각 cmd를 먼저 구독자를 업데이트 한 다음 가입자가 실행 후 트리거 가지의 시리즈를 기다리는 cmd를 실행 잠금, 전체 cmd를 해제했다;
사후 완료 cmd를 cmd를 수행하기 전에, 즉, 리니어 액츄에이터;
각 트랜잭션의 경우,
그것은 선형 액츄에이터입니다 다음 트랜잭션을 실행하기 전에 거래의 완료를 발표 한 후
도구의 사용을 탐험 :
는 sys.dm_tran_locks, 복제 모니터, 최적화 힌트, 플립 플롭의 WAITFOR
질문을 탐색 :
1)
트랜잭션 만에 cmd의 경우, cmd를 실행 시퀀스 트리거 가입자
TestTrigger 및 TestTriggerDst 두 개의 테이블을 포함 SourceExam 게시자 데이터베이스. 트리거하지 않습니다.
DstExam에 대한 가입자 데이터베이스는 테이블 TestTrigger 및 TestTriggerDst이 포함되어 있습니다. 다음과 같이 TestTrigger은 테이블에 트리거를 포함하고 NOT FOR REPLICATION 옵션을 열지 마십시오
발행인이 거래에서 구독자에 터치 트리거를 게시 할 수 있습니다하자 다음 다음 문을 실행
게시자는 또한 아니면 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才开始运行