SQLServer——事务
一、事务的概念及要求
- 事务(TRANSACTION)是作为单个逻辑工作单元执行的一系列操作。
- 多个操作作为一个整体向系统提交,要么都执行,要么都不执行。
- 事务是一个不可分割的工作逻辑单元。
二、例子
银行转账过程就是一个事务
- 它需要俩条UPDATE语句来完成,这俩条语句是一个整体。
- 如果其中任一条出现错误,则整个转账业务也应该取消,俩个账户中的余额应恢复到原来的数据,从而确保转账前和转账后的余额不变。
三、事务的特性
- 原子性:事务是一个完整的操作,事务的各步操作是不可分的,要么都执行,要么都不执行。
- 一致性:当事务完成时,数据必须处于一致状态。
- 隔离性:并发事务之间彼此隔离、独立、它不应该以任何方式依赖于或影响其他事务。
- 永久性:事务完成后,它对数据的修改被永久保存。
四、事务的分类
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