SQLserver中事务的使用

一、有时候我们需要同时执行很多个SQL操作,但是这些要执行的SQL有一部分执行成功了,比如原本应该向几个相互关联的表中插入数据,但是只有其中一个表的数据插入成功了,这时按照正常的逻辑,只要插入其中一个表失败了,那么就应该撤销已经成功了插入操作,这样事务就派上用场了。

二、事务的特性

  1、原子性 事务是一个完整的操作,事务的各操作时不可分的,要么都执行,要么都不执行。
  2、一致性 当事务完成时,数据必须处于一致状态
  3、隔离性 并发事务之间彼此隔离,独立,它不应该以任何方式依赖与或影响其他事务。
  4、永久性 事务完成后,它对数据库的修改会永久行的保存。、

三、事务的三个步骤

  开启事务

  BEGIN TRANSACTION

  这里是要执行的SQL脚本

  if  判断SQL脚本是否产生错误

    如果执行SQL脚本没有出错,那么就执行

    COMMIT TRANSACTION

  else

    如果执行SQL脚本出错,那么就回滚事务

    ROLLBACK TRANSACTION

  

  具体代码如下:

  

DECLARE @errorSum int --定义变量,用于累计事务执行中的错误
set @errorSum = 0; --0代表无错误
--开启事务
begin transaction
    begin
    --SQL操作
    --如果SQL语句发生错误,那么就让错误变量++
    set @errorSum = @errorSum + @@ERROR;--@@ERROR 是一个全局变量,只要发生执行SQL语句错误时,@@ERROR就会自动+1
    if(@errorSum>0)
        --有错误就回滚事务
        rollback transaction
    else
        --没有错误就提交事务
        commit transaction
    end
go

三、事务的应用(在SQLserver中事务通常会结合存储过程一起使用)

  这里举一个简单的例子:如图是一个简单的表,我会写一个存储过程,在存储过程中向表中插入两条数据,第一条会插入成功,但是第二条会出错,出错之后事务就会回滚,让第一条插入SQL也失败。

  

use testdb;
go
if exists(select * from sysobjects where name ='testtransaction')
drop procedure testtransaction
go
create procedure testtransaction
@_user nchar(20),
@_pwd nchar(20),
@score decimal(6,2)
as
    declare @error_count int set @error_count=0;--用于记录错误信息的条数
begin
    begin
        begin transaction
            begin
                insert into userTable(_user,_pwd,score) values('贺兰婷','love123',111);--这一条SQL会成功
                insert into userTable(_user,_pwd,score) values(@_user,@_pwd,@score);--这一条SQL需要在外部调用存储过程时传递参数
          --手动让错误条数加1,然后下面事务就会回滚
                set @error_count = @error_count +1;
                set @error_count = @error_count + @@ERROR;--内部变量@@ERROR 这个表示如果上一条SQL语句出错,那么这一条SQL语句就会执行,错误信息条数就会增加1
                if @error_count >0 --如果错误信息条数大于0 证明在执行SQL的过程中出现了错误,则应当让事务回滚
                    begin
                        print('插入失败!');
                        rollback transaction
                    end
                else
                    begin
                        print('插入成功!');
                        commit transaction
                    end
            end
    end
end;  

下面我们调用一下这个存储过程

begin
    exec testtransaction '你好','你好呀!',8908;
end

执行结果如下:

当插入失败时事务会自动回滚到初始状态,也就是说,我们插入成功的两条数据会失败!

原文地址:https://www.cnblogs.com/yuanshuang-club/p/13527556.html