1. 为什么要使用事务?
当一个存储过程或多个SQL语句(指代insert、update、delete类型)依次执行时候,
如果其中一条或几条发生错误,但是其他的还会继续执行,会造成数据的不一致,非常危险。常见的,比如银行,我们从一个账号
转钱到另一个账号,如果当我们转出的时候,系统发生了故障,但是没有转入,这样的话,银行的数据就出问题。想解决这个问题,我们使用事务!
2. 事务的特点
原子性:就是不可分割性,是一个整体。
一致性:也就是我们操作的数据,前后都保持高度的一致。
3. 主要作用:就是保证数据在不同的操作中,或者这些操作全部成功,或者失败的时候全部取消。
4. 事务的创建和使用(示例代码)
在SQLServer中全局变量使用@@标识
常见的:@@Identity @@error 用来存储SQL操作最后一条语句的状态。
建议:如果你在开发中,使用存储过程,只要是两个或两个以上的insert、update或delete类型的SQL被执行,你就都可以
使用事务。后续扩展:我们在C#应用程序中,如果我们发送的SQL语句,有多个insert或update、delete,同样在C#中也可以直接使用事务。
--首先测试@@error全局变量的使用 if exists(select * from sysobjects where name=‘usp_AddProduct3‘) drop procedure usp_AddProduct3 go create procedure usp_AddProduct3 @ProductId varchar(50), @ProductName varchar(50), @UnitPrice numeric(18,2), @Unit varchar(50), @CategoryId int, @MinCount int, @MaxCount int as declare @errorSum int --@errorSum这个变量用来记录错误号码的总数 --在商品信息表中,添加数据 insert into Products(ProductId, ProductName, UnitPrice, Unit, CategoryId) values(@ProductId, @ProductName, @UnitPrice, @Unit, @CategoryId) select @@error --同时在商品库存表中,添加数据 insert into ProductInventory(ProductId, MinCount, MaxCount, TotalCount,StatusId) values(@ProductId, @MinCount, @MaxCount,0, -2) select 错误号码=@@error go --观察错误号码 exec usp_AddProduct3 ‘6005004003599‘,‘测试商品1‘,1,‘箱‘,10,100,200
-----------------------------------------------------事务----------------------------------------------------------- --建立两个一对一错的存储过程测试事务的作用 if exists(select * from sysobjects where name=‘Course__Procedure4‘) drop procedure Course__Procedure4 go create procedure Course_Procedure4 --定义参数 @CourseName nvarchar(50), @CourseContent nvarchar(500), @ClassHour int, @Credit int, @CategoryId int, @TeacherId int as --编写具体的存储过程内容 insert into Course(CourseName,CourseContent,ClassHour,Credit,CategoryId,TeacherId) values(@CourseName,@CourseContent,@ClassHour,@Credit,@CategoryId,@TeacherId); go exec Course_Procedure4 ‘Emgucv图像处理教程‘,‘C#版本的图像处理1‘,300,10,12,2000 --会继续执行 exec Course_Procedure4 ‘Emgucv图像处理教程‘,‘C#版本的图像处理2‘,300,10,30,2000 --会出错 select * from Course where CourseName=‘Emgucv图像处理教程‘; --综上所述,事务的作用,使得存储过程执行多个增删改查任务时同时成功或者同时失败 --编写事务 if exists(select * from sysobjects where name=‘Course__Procedure5‘) drop procedure Course__Procedure5 go create procedure Course__Procedure5 --定义参数 @CourseName nvarchar(50), @CourseContent nvarchar(500), @ClassHour int, @Credit int, @CategoryId int, @TeacherId int, @CategoryName varchar(50) as declare @errorNum int;---定义变量 set @errorNum=0;--设置初始值 --开启事务 begin transaction begin --编写具体的存储过程内容 insert into Course(CourseName,CourseContent,ClassHour,Credit,TeacherId,CategoryId) --可能出错 values(@CourseName,@CourseContent,@ClassHour,@Credit,@TeacherId,@CategoryId); set @errorNum+=@@error print @errorNum; insert into CourseCategory(CategoryName) --不会出错 values(@CategoryName); set @errorNum+=@@error print @errorNum; if(@errorNum>0) --有错误 rollback transaction --回滚事务 else --无错误 commit transaction --提交事务 end go --调用事务 exec Course__Procedure5 ‘Emgucv图像处理‘,‘C#板opencv‘,300,10,200,2000,‘.NET系列课程‘ --出错 exec Course__Procedure5 ‘Emgucv图像处理‘,‘C#板opencv‘,300,10,12,2000,‘.NET系列课程‘ --执行成功 select * from CourseCategory
事务的作用就是要么全部成功,要么回到执行事务前的状态。