我在表 A 上有一个从表 B 中删除的删除触发器。我正在测试触发器失败时会发生什么,为此我重命名了表 B,因此触发器找不到它。
这些是我的正常步骤:
begin transaction
delete from C
delete from A -- this errors for reason mentioned
-- At this point the transaction is automatically rolled-back.
但是,如果我执行以下步骤:
begin transaction
delete from C
delete from B -- this errors for reason mentioned
-- At this point transaction is not rolled back, and I can still commit it.
在第一种情况下,事务如何回滚?难道不应该由应用程序调用回滚或提交吗?
整个区别在于触发器失败与语句失败的原因相同,我希望行为是相同的。
编辑以添加示例:
create table A (a int primary key)
create table B (a int primary key)
create table C (a int primary key)
create trigger Atrig on A for delete as delete B from B, deleted where B.a=deleted.a
insert into A values(1)
insert into A values(2)
insert into B values(2)
insert into B values(3)
insert into C values(1)
insert into C values(2)
insert into C values(3)
现在将表 B 重命名为 B2(我使用 UI 重命名它,所以没有 sql 命令这样做)
begin transaction
delete C where a=3
delete A where a = 2
以上返回此错误,并回滚事务:
System.Data.OleDb.OleDbException (0x80040E37): [42000]
[Message Class: 16]
[Message State: 1]
[Transaction State: 0]
[Server Name: sybase_15_5_devrs1]
[Procedure Name: Atrig]
[Line Number: 1]
[Native Code: 208]
[ASEOLEDB]B not found. Specify owner.objectname or use sp_help to check whether the object exists (sp_help may produce lots of output).
但是,如果我这样做:
begin transaction
delete C where a=3
delete B where a = 2
上面返回错误,但事务没有回滚,我可以发出'提交事务':
System.Data.OleDb.OleDbException (0x80040E37): [42000]
[Message Class: 16]
[Message State: 1]
[Transaction State: 0]
[Server Name: sybase_15_5_devrs1]
[Native Code: 208]
[ASEOLEDB]B not found. Specify owner.objectname or use sp_help to check whether the object exists (sp_help may produce lots of output).
我认为该行为与此主题有关 在“数据修改错误导致的回滚”表中,它说:
Context: Transaction only
Behavior: Current command is aborted. Previous commands are not rolled back, and subsequent commands are executed.
Context: Trigger in a transaction
Behavior: Trigger completes, but trigger effects are rolled back.
All data modifications since the start of the transaction are rolled back. If a transaction spans multiple batches, the rollback affects all of those batches.
Any remaining commands in the batch are not executed. Processing resumes at the next batch.