事务
就是将一推脚本代码放在一起,并将其作为一个整体
可以控制这些代码执行完成以后,是否保留执行结果
还是执行代码以后,就和没有执行一样(不起效果)
语法:
begin transaction --开启一个事务
--其后的所有代码都是一个整体,表示可以使用一定语句限制这些代码是否起作用
begin try
--sql 语句
commit;--表示事务提交
end try
begin catch
rollback;--表示回滚
end catch
go
1 begin transaction 2 declare @myError int; 3 set @myError = 0; 4 begin try 5 update bank set balance=balance - @balance where cid=@from; 6 update bank set balance=balance + @balance where cid=@to; 7 commit; 8 set @res = 1; --表示成功 9 end try 10 begin catch 11 rollback; 12 set @res = 0; --表示失败 13 end catch 14 go
另一种方式:
1 begin transaction 2 declare @myError int; 3 set @myError = 0; 4 update bank set balance=balance - 1000 where cid='0001'; 5 set @myError = @myError + @@ERROR; 6 update bank set balance=balance + 1000 where cid='0002'; 7 set @myError = @myError + @@ERROR; 8 if(@myError > 0) 9 begin 10 rollback 11 end 12 else 13 begin 14 commit 15 end; 16 go
在正常情况下数据库的处理均是事务
-> 我们执行的一个插入,删除等等一系列操作,每一句话都是一个事务(SQL Server 默认)
-> 事务处理是一个原子操作
-> 只有提交以后,数据才会受影响
-> 异常,出错以后会爆红,表示执行代码有问题
-> 即使使用@@error变量记录出错信息,但是这么执行在C#中就是异常
-> 考虑异常代码块
-> 在使用事务的时候容易出现锁的概念
-> 如果一个数据表在被修改,那么这张表就得到了“排他锁”
-> 如果一个数据在读取一张表,那么这张表就得到了“共享锁”
共享锁(S锁):
如果事务T对数据A加上共享锁后,则其他事务只能对A再加共享锁,不能加排他锁。获准共享锁的事务只能读数据,不能修改数据。
排他锁(X锁):
如果事务T对数据A加上排他锁后,则其他事务不能再对A加任任何类型的封锁。获准排他锁的事务既能读数据,又能修改数据。
简要说明为什么会发生死锁?解决死锁的主要方法是什么?
若干事务相互等待释放封锁,就陷入无限期等待状态,系统就进入死锁
解决死锁的方法应从预防和解除的两个方面着手:
(1)死锁的预防方法:①要求每一个事务必须一次封锁所要使用的全部数据(要么全成功,要么全不成功)②规定封锁数据的顺序,所有事务必须按这个顺序实行封锁。
(2)允许死锁发生,然后解除它,如果发现死锁,则将其中一个代价较小的事物撤消,回滚这个事务,并释放此事务持有的封锁,使其他事务继续运行。
(3)对数据库添加分布式应用,进行读写分离能有效的减低死锁的概率!