简介
事务是一个用户定义的完整的工作单元,一个事务内的所有语句被作为整体执行,要么全部执行,要么全部不执行。遇到错误时,可以回滚事务,取消事务内所做的所有改变,从而保证数据库中数据的一致性和可恢复性。
事务的特性
原子性:事务是数据库的逻辑工作单位,事务中的操作要么都做,要么都不做。
一致性:事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。
隔离性:一事务的执行不能被其它事务干扰。
持续性(永久性):指事务一旦提交,则其对数据库中数据的改变就应该是永久的
事务和批的区别
批是一组整体编译的SQL语句,事务是一组作为单个逻辑工作单元执行的SQL语句。
批语句的组合发生在编译时刻,事务中语句的组合发生在执行时刻。
当在编译时,批中某个语句存在语法错误,系统将取消整个批中所有语句执行,而在运行时刻,如果事务中某个数据修改违反约束、规则等,系统默认只回退产生该错误的语句。
显式事务
显式事务是指由用户执行T-SQL事务语句而定义的事务。
BEGIN TRANSACTION
:标识一个事务的开始,即启动事务。
COMMIT TRANSACTION、COMMIT WORK
:标识一个事务的结束,事务内所修改的数据被永久保存到数据库中。
ROLLBACK TRANSACTION、ROLLBACK WORK
:标识一个事务的结束,说明事务执行过程中遇到错误,事务内所修改的数据被回滚到事务执行前的状态。
隐式事务
在隐式事务模式下,在当前事务提交或回滚后,SQL Server自动开始下一个事务。
执行SET IMPLICIT_TRANSACTIONS ON
语句可使SQL Server进入隐式事务模式。
需要关闭隐式事务模式时,调用SET IMPLICIT_TRANSACTIONS OFF
语句关闭。
自动事务
在自动事务模式下,当一个语句被成功执行后,它被自动提交,而当它执行过程中产生错误时,被自动回滚。
自动事务模式是SQL Server的默认事务管理模式。
事务错误处理
- 使用
@@error
全局变量
USE 教学管理
GO
DECLARE @del_error int, @ins_error int
-- 开始一个事务
BEGIN TRAN
-- 删除一个学生
DELETE 学生表 WHERE 学号 = 'S060308'
-- 为删除语句设置一个接受错误数值的变量
SELECT @del_error = @@ERROR
--再执行插入语句
INSERT INTO 学生表
VALUES('S060308','******19890526***','张丹宁','男',
'130***12','宁波','电子商务','信息学院', 162)
--为插入语句设置一个接受错误数值的变量
SELECT @ins_error = @@ERROR
--测试错误变量中的值
IF @del_error = 0 AND @ins_error = 0
BEGIN
--成功,提交事务
COMMIT TRAN
END
ELSE
BEGIN
-- 有错误发生,回滚事务
IF @del_error <> 0
PRINT '错误发生在删除语句'
IF @ins_error <> 0
PRINT '错误发生在插入语句'
ROLLBACK TRAN
END
GO
- 使用
TRY...CATCH
BEGIN TRY
BEGIN TRANSACTION
……
COMMIT TRANSACTION
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION
END CATCH
- 使用
SET XACT_ABORT ON
事务错误处理总结
- 自动事务模式
在自动事务模式下,只有出错的语句不会执行,而其他无错语句会正常执行。
在自动事务模式下,打开XACT_ABORT
开关后,不仅出错的语句不会执行,并且出错语句之后的语句也不会执行,但出错语句之前已经执行的语句不会回滚(因为在自动事务模式下,每个SQL语句都是一个单独的事务,打开XACT_ABORT
开关仅仅是中断当前事务的执行并回滚,但不会影响已经提交的事务)。
- 显示事务模式
在显式事务模式下,如果不加入异常处理和回滚程序,出错的语句不会执行,而其他无错语句会正常执行。
在显式事务模式下,打开XACT_ABORT
开关后,不仅出错的语句不会执行,并且出错语句之后的语句也不会执行,而且出错语句之前已经执行的语句会回滚。
在显式事务模式下加入了异常处理程序( try...catch
)后,当程序执行到出错语句后,会跳转到CATCH段回滚整个事务已经完成的操作(出错语句之后的语句不再执行)。
在显式事务模式下加入了错误处理程序(@@error
)后,如果当事务执行完毕后检查错误代码汇总值发现事务执行过程中至少有一个语句有错,则回滚整个事务。但是如果有打印的操作,并不会将打印的操作进行回滚。
- 隐式事务模式
在隐式事务模式下,如果不加入异常处理和回滚程序,出错的语句不会执行,而其他无错语句会正常执行(与显式事务模式的区别在于不用“BEGIN TRANSACTION”开始一个事务)。