mssql sqlserver 触发器中的事务操作说明


摘要:
下文讲述sqlserver触发器中的事务相关知识


当数据库中触发器被触发器时,此时触发器中的语句就会被包含到当前触发的sql脚本中,
作为一组代码块进行处理。

显式指定事务

当我们在sql脚本中放入事务的开始和结束设置,触发器中代码块也会被包含在事务的代码块中,触发器中可以回滚代码块中的事务

隐式指定事务

当我们不对sql脚本块指定事务时,触发器中的脚本和触发它的脚本可一起组成隐式的事务


例:

    create table [maomao365]
    (keyId int  not null,info varchar(30) not null )
  go
 
----为表maomao365创建 insert update触发器
  create trigger tr_maomao365
   on [maomao365]
   as
    set noconut on
      if exists (select null from inserted  
            where keyId =0
        )
      begin
          rollback tran
      end
         set noconut off
      go

    insert into [maomao365]
    (keyId,info)values(0,'test')
    go

当我们执行insert into 语句,由于keyId值插入为0,违反了触发器中的where 条件,被触发器中的事务回滚掉,所以数据表中不会出现刚刚插入的数据。


   insert into [maomao365]
  (keyId,info)values(2,N'sql教程')
   insert into [maomao365]
    (keyId,info)values(0,N'sqlblog')

同时执行以上语句,当运行到第二条时,会被触发器拦截,但第一条sql插入语句会被正常的运行并提交


   begin tran
    insert into [maomao365]
  (keyId,info)values(2,N'sql教程')
 
   insert into [maomao365]
    (keyId,info)values(0,N'sqlblog')
  if @@error <>0
   begin
     rollback tran
     return;
    end
   
  commit tran;
  return;

当我们在语句块中,开始一个事务,触发器中会自动嵌套一个事务,触发器中rollback transaction语句回滚
嵌套事务将被忽略,将直接回滚到最外面的begin trans



触发器中回滚部分事务

当我们想在触发器中回滚部分事务,使触发器中的事务不影响触发的脚本时,此时我们可以采用保存事务点的方式

   ----为表maomao365创建 insert update触发器
  create trigger tr_maomao365
   on [maomao365]
   as
    set noconut on
     save transaction tranInfo
      if exists (select null from inserted  
            where keyId =0
        )
      begin
          rollback tran  tranInfo
      end
         set noconut off
      go
      insert into  [maomao365]
     (keyId,info)values(0,'aaaa')
     go

此时我们就会发现keyId为0的值被插入到数据表中,因为触发器中的事务只回滚自身事务部分。