Drop/Create 事务中的触发器问题 - 请问触发器 运行 之后
Drop/Create Triggers in a Transaction Question - Will the trigger run after
我想询问在事务开始时删除然后在事务结束时重新创建的触发器(比方说 "after update" 触发器)的行为,具体来说,触发器 运行 会在事务的提交阶段(假设在事务中间我执行了一些通常会触发触发器的脚本)吗?
考虑这个例子。
- 开始交易
- 掉落触发器
- 运行 对 table 进行更改的脚本通常会触发(删除的)触发器
- 重新创建(丢弃的)触发器
- 提交交易
在第 5 行,当数据库提交整个事务时,重新创建的触发器是否 运行?
更新
如果这不是 possible/or 这样做的好主意,我想重新表述这个问题。而不是 dropping/re-creating,我相信更好的解决方案是 disable/enable 触发器。在此,启用触发器后,是否会在交易结束时运行?
更新 2
根据大家的建议,我的场景是这样的:
开始发送
禁用触发,运行 SQL,启用触发
提交 TX
触发器不会触发,这正是我想要的。
如果您禁用触发器,然后执行并提交事务,然后重新启用触发器,触发器将不会 "run" 用于已完成的事务。
如果您在 DML 语句和 COMMIT 之间启用触发器,触发器将不会 运行;例如,这不会导致触发器执行:
BEGIN TRANSACTION;
ALTER TABLE [dbo].[myTable] DISABLE TRIGGER [trg_trgtest]
UPDATE [dbo].[myTable]
SET [language] = 'fr'
WHERE id = 6
ALTER TABLE [dbo].[myTable] ENABLE TRIGGER [trg_trgtest]
COMMIT;
删除触发器会在 table 上放置一个独占元数据锁 (Sch-M),以防止在交易。
EG
use tempdb
go
drop table if exists foo
go
create table foo(id int primary key)
go
create trigger tg_foo on foo after insert
as
begin
select 'tg_foo trigger running' msg
end
go
begin transaction
go
drop trigger tg_foo
go
select o.name, o.type_desc, request_mode
from sys.dm_tran_locks tl
join sys.objects o
on o.object_id = tl.resource_associated_entity_id
where request_session_id = @@spid
and o.is_ms_shipped = 0
optputs
name type_desc request_mode
------------------- ----------- --------------
foo USER_TABLE Sch-M
(1 row affected)
因此,当您在事务开始时删除触发器时,对该 table 的所有访问都将被阻止,直到您提交或回滚该事务。
等等
will the trigger run during the commit phase of the transaction
(assuming that in the middle of the transaction I executed some
scripts that would normally trigger the trigger)?
因此在提交时,通常 "trigger the trigger" 的脚本将变得畅通无阻,并且 运行,正常触发触发器。
我想询问在事务开始时删除然后在事务结束时重新创建的触发器(比方说 "after update" 触发器)的行为,具体来说,触发器 运行 会在事务的提交阶段(假设在事务中间我执行了一些通常会触发触发器的脚本)吗?
考虑这个例子。
- 开始交易
- 掉落触发器
- 运行 对 table 进行更改的脚本通常会触发(删除的)触发器
- 重新创建(丢弃的)触发器
- 提交交易
在第 5 行,当数据库提交整个事务时,重新创建的触发器是否 运行?
更新
如果这不是 possible/or 这样做的好主意,我想重新表述这个问题。而不是 dropping/re-creating,我相信更好的解决方案是 disable/enable 触发器。在此,启用触发器后,是否会在交易结束时运行?
更新 2
根据大家的建议,我的场景是这样的:
开始发送 禁用触发,运行 SQL,启用触发 提交 TX
触发器不会触发,这正是我想要的。
如果您禁用触发器,然后执行并提交事务,然后重新启用触发器,触发器将不会 "run" 用于已完成的事务。
如果您在 DML 语句和 COMMIT 之间启用触发器,触发器将不会 运行;例如,这不会导致触发器执行:
BEGIN TRANSACTION;
ALTER TABLE [dbo].[myTable] DISABLE TRIGGER [trg_trgtest]
UPDATE [dbo].[myTable]
SET [language] = 'fr'
WHERE id = 6
ALTER TABLE [dbo].[myTable] ENABLE TRIGGER [trg_trgtest]
COMMIT;
删除触发器会在 table 上放置一个独占元数据锁 (Sch-M),以防止在交易。
EG
use tempdb
go
drop table if exists foo
go
create table foo(id int primary key)
go
create trigger tg_foo on foo after insert
as
begin
select 'tg_foo trigger running' msg
end
go
begin transaction
go
drop trigger tg_foo
go
select o.name, o.type_desc, request_mode
from sys.dm_tran_locks tl
join sys.objects o
on o.object_id = tl.resource_associated_entity_id
where request_session_id = @@spid
and o.is_ms_shipped = 0
optputs
name type_desc request_mode
------------------- ----------- --------------
foo USER_TABLE Sch-M
(1 row affected)
因此,当您在事务开始时删除触发器时,对该 table 的所有访问都将被阻止,直到您提交或回滚该事务。
等等
will the trigger run during the commit phase of the transaction (assuming that in the middle of the transaction I executed some scripts that would normally trigger the trigger)?
因此在提交时,通常 "trigger the trigger" 的脚本将变得畅通无阻,并且 运行,正常触发触发器。