1.什么是事务
1.1定义
事务就是被绑定在一起作为一个逻辑工作单元的SQL语句组,如果任何一个语句操作失败那么整个操作就被失败,进而回滚到操作前状态,或者是上个节点。为了确保要么执行,要么不执行,就可以使用事务。
1.2特性
- 原子性(atomicity) 一个事务是一个不可分割的工作单位,事务中包括的诸操作要么都做,要么都不做。
- 一致性(consistency) 事务必须是使数据库从一个一致性状态变到另一个一致性状态。
- 隔离性(isolation) 一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
- 持久性(durability) 持续性也称永久性(permanence),指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。
1.3 几种常见事务
- 自动提交事务: 是SQL Server默认的一种事务模式,每条Sql语句都被看成一个事务进行处理。比如一条Update 修改2个字段的语句,不会只修改一个字段而第二个字段没有被修改。
- 显示事务: 我们常用的事务,由Begin Transaction开启事务开始,由Commit Transaction 提交事务、Rollback Transaction 回滚事务结束。
- 隐式事务: 使用Set IMPLICIT_TRANSACTIONS ON 将将隐式事务模式打开,不用Begin Transaction开启事务,当一个事务结束,这个模式会自动启用下一个事务,只用Commit Transaction 提交事务、Rollback Transaction 回滚事务即可。
2.事务的应用
2.1基本语句
- Begin Transaction: 开始事务。
- Rollback Transaction: 回滚事务,当数据处理中出错时,回滚到没有开始处理前的状态,或者回滚到事务的保存点。
- Save Transaction: 保存点,事务回滚时不会全部回滚而是回滚到保存点处。
- Commit Transaction: 提交事务。
2.2 实例
2.2.1数据库
USE [job]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Customers](
[ID] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](50) NULL,
[Country] [nvarchar](50) NULL,
[Sex] [bit] NULL,
[ConsumeAmount] [int] NULL,
[ConsumeLevel] [nvarchar](50) NULL,
[Remain] [decimal](18, 0) NULL,
CONSTRAINT [PK_Customers] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[Customers] WITH CHECK ADD CONSTRAINT [CK_Customers] CHECK (([remain]<(2000)))
GO
ALTER TABLE [dbo].[Customers] CHECK CONSTRAINT [CK_Customers]
GO
2.2.2代码
--实现金额转账的功能
--为了能使事务多次调用,用存储过程来保存事务
--创建保存事务的存储过程
create proc cp_remain
(
@idIn int, --转账人ID
@idOut int, --接收人ID
@money decimal(18, 0) --转账金额
)
as
--事务的语法
BEGIN TRAN Tran_Money --开始事务
--定义变量用于记录错误数
DECLARE @tran_error int;
SET @tran_error = 0;
BEGIN TRY
UPDATE Customers SET Remain = Remain - @money WHERE ID=@idIn --将转账人的金额减少
SET @tran_error = @tran_error + @@ERROR; --记录错误数
UPDATE Customers SET Remain = Remain + @money WHERE ID=@idOut --将接收人的金额增加
SET @tran_error = @tran_error + @@ERROR; --记录错误数
END TRY
--如果处理数据中有失败就执行里面的代码
BEGIN CATCH
PRINT '出现异常,错误编号:' + convert(varchar,error_number()) + ',错误消息:' + error_message()
SET @tran_error = @tran_error + 1
END CATCH
IF(@tran_error > 0)
BEGIN
--执行出错,回滚事务
ROLLBACK TRAN;
PRINT '转账失败,取消交易!';
END
ELSE
BEGIN
--没有异常,提交事务
COMMIT TRAN;
PRINT '转账成功!';
END