SQL SERVER 事务和锁

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/marko_zheng/article/details/86015621

SQL SERVER 事务和锁

事务:保持逻辑数据一致性与可恢复性,必不可少的利器。

锁:多用户访问同一数据库资源时,对访问的先后次序权限管理的一种机制,没有他事务或许将会一塌糊涂,不能保证数据的安全正确读写。

/*******************************************************************************************************************************/
先举一个典型的业务

A给B转账100元

在数据库中 实际进行了两步操作

  • A的账户减掉100元
  • B的账户增加100元

这两个动作应当构成一个不可分割的整体,要么完成其中的所有动作,要么不执行其中任何动作

这两个动作就是一种“不可分割”的业务单 位 。一旦某个环节失败,就需要回滚(恢复到初始状态)
/*******************************************************************************************************************************/

事务的特性

  • 原子性:事务必须是一个自动工作的单元,要么全部执行,要么全部不执行。
  • 一致性:事务结束的时候,所有的内部数据都是正确的。
  • 隔离性:并发多个事务时,各个事务不干涉内部数据,处理的都是另外一个事务处理之前或之后的数据。
  • 持续性:事务提交之后,数据是永久性的,不可再回滚。

事务的常用语句

    Begin Transaction:标记事务开始。
    Commit Transaction:事务已经成功执行,数据已经处理妥当。
    Rollback Transaction:数据处理过程中出错,回滚到没有处理之前的数据状态,或回滚到事务内部的保存点。
    Save Transaction:事务内部设置的保存点,就是事务可以不全部回滚,只回滚到这里,保证事务内部不出错的前提下。

创建一个事务 把id为6的stu_id改为2014100766,stu_math改成100,id值不存在于表中,则事务回滚,不执行

--创建一个事务 把id为6的stu_id改为2014100766
begin tran test_tran
update stu set stu_id = concat(201410076,stu_id) where id = 6
update stu set stu_math=100 where id = 6
if @@ERROR!=0
	rollback transaction
else
	commit tran test_tran

用try catch再写一遍

--try catch 再写一遍
begin tran test_tran2

begin try
    --把id为7的stu_id改为201410076
	update stu set stu_id = concat(201410076,stu_id) where id = 7
end try
begin catch
select Error_number() as ErrorNumber,  --错误代码
           Error_severity() as ErrorSeverity,  --错误严重级别,级别小于10 try catch 捕获不到
           Error_state() as ErrorState ,  --错误状态码
           Error_Procedure() as ErrorProcedure , --出现错误的存储过程或触发器的名称。
           Error_line() as ErrorLine,  --发生错误的行号
           Error_message() as ErrorMessage  --错误的具体信息
    if(@@trancount>0) --全局变量@@trancount,事务开启此值+1,他用来判断是有开启事务
       rollback tran  ---由于出错,这里回滚到开始,第一条语句也没有插入成功。
end catch

if(@@trancount>0)
 commit tran test_tran2  

/------------------------------------------------01-08------------------------------------

写一个存储过程,根据传入的参数,修改学生成绩,姓名

--  创建一个修改学生信息和成绩的存储过程
go
create procedure test_tran_procedure
	@id varchar(200)='',
	@stu_id varchar(200)='',--学生stu_id
	@stu_name varchar(200)='',--姓名
	@stu_chinese varchar(200)='', --语文
	@stu_math varchar(200)='',--数学
	@stu_english varchar(200)='', --英语
	@stu_total varchar(200)='' --总成绩
as
begin tran
begin try
	--执行语句
	if(@id = '')
		print '警告信息:id请勿为空';
		rollback tran  --如果id 不传 语句不执行
	if(@stu_id!='')
		update stu set stu_id = @stu_id where id = @id --用户传入stuid 则修改stu_id
	if(@stu_name!='')
		update stu set stu_name = @stu_name where id = @id
	if(@stu_chinese!='')
		update stu set stu_chinese = @stu_chinese where id = @id
	if(@stu_math!='')
		update stu set stu_math = @stu_math where id = @id
	if(@stu_english!='')
		update stu set stu_english = @stu_english where id = @id
	if(@stu_total!='')
		update stu set stu_total = @stu_total where id = @id
	--如果不传参数,事务回滚
	
end try
begin catch
select Error_number() as ErrorNumber,  --错误代码
           Error_severity() as ErrorSeverity,  --错误严重级别,级别小于10 try catch 捕获不到
           Error_state() as ErrorState ,  --错误状态码
           Error_Procedure() as ErrorProcedure , --出现错误的存储过程或触发器的名称。
           Error_line() as ErrorLine,  --发生错误的行号
           Error_message() as ErrorMessage  --错误的具体信息
    if(@@trancount>0) --全局变量@@trancount,事务开启此值+1,他用来判断是有开启事务
       rollback tran  ---由于出错,这里回滚到开始
end catch
if(@@trancount>0)
	commit tran 
--调用存储过程
exec test_tran_procedure @stu_id = '1111111111';

exec test_tran_procedure @id = '6',@stu_id = '20141007123',
	@stu_name='',@stu_chinese='',@stu_math='',@stu_english='',@stu_total='1001';

猜你喜欢

转载自blog.csdn.net/marko_zheng/article/details/86015621