SQLServer——事务

一、事务的概念及要求

  1. 事务(TRANSACTION)是作为单个逻辑工作单元执行的一系列操作。
  2. 多个操作作为一个整体向系统提交,要么都执行,要么都不执行。
  3. 事务是一个不可分割的工作逻辑单元。

 

二、例子

银行转账过程就是一个事务

  1. 它需要俩条UPDATE语句来完成,这俩条语句是一个整体。
  2. 如果其中任一条出现错误,则整个转账业务也应该取消,俩个账户中的余额应恢复到原来的数据,从而确保转账前和转账后的余额不变。

 

三、事务的特性

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

 

四、事务的分类

1、显示事务

用 BEGIN TRANSACTION 明确指定事务的开始,是最常用的事务。

 

2、隐性事务

通过设置 SET IMPLICIT_TRANSACTIONS ON 语句,将隐性事务模式设置为打开。

其后的 T-SQL语句自动启动一个新事务。

提交或回滚一个事务后,下一个 T-SQL 语句又将启动一个新事务。

 

3、自动提交事务

SQL Server 的默认模式。

每条单独的 T-SQL 语句视为一个事务。

 

五、使用 SQL 语句管理事务的基本步骤

一旦事务提交或者回滚,则事务结束

1、开始事务

BEGIN TRANSACTION

 

2、提交事务

COMMIT TRANSACTION

 

3、回滚(撤销)事务

ROLLBACK TRANSACTION

 

4、事务处理中的关键问题

对事务中的insert、update、delete语句实时跟踪。

 

5、判断某条语句执行是否出错的方法

  • 使用全局变量@@ERROR。
  • @@ERROR只判断当前一条T-SQL语句执行是否出错。
  • 为了判断事务中所有T-SQL语句是否有错,可以对错误进行累计。
  • SET @errorSum=@errorSum+@@ERROR

 

六、例子

银行转账。要么转出、转入都成功,要么都不成功。

use StudentManageDB
go
select * from CardAccount
declare @errorSum int --定义变量,用于累计事务执行汇总的错误
set @errorSum=0 --初始化为0,代表没有错误
begin transaction
    begin
        --转出
        update CardAccount set CurrentMoney=CurrentMoney-1000 where StudentId=100001
        set @errorSum=@errorSum+@@error --累计是否有错误
        --转入
        update CardAccount set CurrentMoney=CurrentMoney+1000 where StudentId=10002
        set @errorSum=@errorSum+@@error
        if(@errorSum>0)
            rollback transaction
        else
            commit transaction
    end
go

 

七、事务结合存储过程使用

编写存储过程,实现学员一卡通转账功能,要求用户输入转入和转出的金额和账户

use StudentManageDB
go
if exists(select * from Sysobjects where name='usp_TransferAccounts')
drop procedure usp_TransferAccounts
go
create procedure usp_TransferAccounts
@inputAccount int, --转入账户
@outputAccount int, --转出账户
@transferMoney int --交易金额
as
    declare @errorSum int --定义变量,用于累计事务执行中的错误
    set @errorSum=0 --初始化为0,代表没有错误
    begin transaction
        begin
            --转出
            update CardAccount set CurrentMoney=CurrentMoney-@transferMoney where StudentId=@outputAccount
            set @errorSum=@errorSum+@@error
            --转入
            update CardAccount set CurrentMoney=CurrentMoney+@transferMoney where StudentId=@inputAccount
            set @errorSum=@errorSum+@@error --累计是否有错误
            if(@errorSum>0)
                rollback transaction
            else
                commit transaction
        end
go


--测试失败的转账
exec usp_TransferAccounts 100002,100001,1000
--查询余额
select * from CardAccount

--测试转账成功
exec usp_TransferAccounts 100002,100001,800
--查询余额
select * from CardAccount
posted @ 2019-12-30 22:59  徐林俊  阅读(380)  评论(0编辑  收藏  举报