SQLSever事务

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

事务的作用就是要么全部成功,要么回到执行事务前的状态。

 

posted @ 2021-03-28 19:48  WellMandala  阅读(106)  评论(0编辑  收藏  举报