SQL Server中的事物
1.事务的四个属性
原子性Atomicity,一致性Consistency,隔离性Isolation,持久性Durability ,即ACID特性。
原子性:事务必须是一个完整工作的单元,要么全部执行,要么全部不执行。
一致性:事务结束的时候,所有的内部数据都是正确的。
隔离性:并发多个事务时,各个事务不干涉内部数据,处理的都是另外一个事务处理之前或之后的数据。
持久性:事务提交之后,数据是永久性的,不可再回滚。
2.在SQL Server中事务被分为3类常见的事务
自动提交事务:是SQL Server默认的一种事务模式,每条Sql语句都被看成一个事务进行处理。如果成功执行,则自动提交,如果错误,则自动回滚。
显式事务:T-sql标明,由Begin Transaction开启事务开始,由Commit Transaction 提交事务、Rollback Transaction 回滚事务结束。
隐式事务:使用Set IMPLICIT_TRANSACTIONS ON 将将隐式事务模式打开,不用Begin Transaction开启事务。当一个事务结束,这个模式会自动启用下一个事务,只用Commit Transaction 提交事务、Rollback Transaction 回滚事务即可。
3.事物的语法
Begin Transaction:标记事务开始。
Commit Transaction:事务已经成功执行,数据已经处理妥当。
Rollback Transaction:数据处理过程中出错,回滚到没有处理之前的数据状态,或回滚到事务内部的保存点。
Save Transaction:事务内部设置的保存点,就是事务可以不全部回滚,只回滚到这里,保证事务内部不出错的前提下。
4.示例
---开启事务
begin tran
begin try --在这里我们可以添加错误的扑捉机制
insert into A(id,name,typeid) values (1,'小王',1) --语句正确
-- save tran pigOneIn --在这里我们可以添加保存点,保存之前正确的数据
insert into A(id,name,typeid) values (2,'小李','学生') --语句类型错误
insert into A(id,name,typeid) values (1,'小张',2) --语句正确
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 --出错回滚,A表中0条数据
-- rollback tran pigOneIn --出错回滚,A表中1条数据
end catch
if(@@trancount>0)
commit tran
SELECT * FROM A --如果成功A表中,将会有3条数据。
5.使用set xact_abort
指定是否回滚当前事务(xact_abort on/off) , 为on时,如果当前sql出错,回滚整个事务,为off时,如果sql出错回滚当前sql语句,其它语句照常运行读写数据库。
注意:xact_abort只对运行时出现的错误有用,如果sql语句本身存在错误,那么xact_abort就没用了。
示例:
set xact_abort off
begin tran
insert into A(id,name,typeid) values (1,'小王',1) --语句正确
insert into A(id,name,typeid) values (2,'小李',12313212313212313) --算术溢出错误,将插入其他两条。如果这里是'学生', xact_abort将失效,不插入任何数据
insert into A(id,name,typeid) values (1,'小张',2) --语句正确
commit tran
select * from A
6.事物并发
在多用户都用事务同时访问同一个数据资源的情况下,就会造成以下几种数据错误。
更新丢失:多个用户同时对一个数据资源进行更新,必定会产生被覆盖的数据,造成数据读写异常。
不可重复读:如果一个用户在一个事务中多次读取一条数据,而另外一个用户则同时更新啦这条数据,造成第一个用户多次读取数据不一致。
脏读:第一个事务读取第二个事务正在更新的数据表,如果第二个事务还没有更新完成,那么第一个事务读取的数据将是一半为更新过的,一半还没更新过的数据,这样的数据毫无意义。
幻读:第一个事务读取一个结果集后,第二个事务,对这个结果集经行增删操作,然而第一个事务中再次对这个结果集进行查询时,数据发现丢失或新增
我们用锁定正在操作的数据,来解决这些问题,当一个事务对一些数据块进行操作的时候,另外一个事务则不能插足这些数据块。
锁定从数据库角度看大致可以分为6种:
共享锁(S):用于读操作(SELECT),还可以叫它读锁。多个事务可以并发读取数据,但任何事务都不能修改数据,直到数据读取完成,共享锁释放。S锁通常数据被读取完毕,立即被释放。
排它锁(X):用于写操作( INSERT、DELETE),还可以叫他独占锁、写锁。仅允许一个事务处理数据,也就是说如果你对数据资源进行增删改的操作时,其它任何事务不允许操作这块资源,直到排它锁被释放,防止同时对同一资源进行多重操作。X锁一直到事务结束才能被释放。
更新锁(U):用来预定要对此页施加X锁,它允许其它事务读,但不允许再施加U。U锁是为了防止出现死锁模式,当两个事务对一个数据资源进行先读取在修改的情况下,使用共享锁和排它锁有时会出现死锁现象,而使用更新锁则可以避免死锁的出现。资源的更新锁一次只能分配给一个事务,如果需要对资源进行修改,更新锁会变成排他锁,否则变为共享锁。U锁一直到事务结束时才能被释放。
意向锁:SQL Server需要在层次结构中的底层资源上(如行,列)获取共享锁,排它锁,更新锁。例如表级放置了意 向共享锁,就表示事务要对表的页或行上使用共享锁。在表的某一行上上放置意向锁,可以防止其它事务获取其它不兼容的的锁。意向锁可以提高性能,因为数据引 擎不需要检测资源的每一列每一行,就能判断是否可以获取到该资源的兼容锁。意向锁包括三种类型:意向共享锁(IS),意向排他锁(IX),意向排他共享锁 (SIX)。
架构锁:防止修改表结构时,并发访问的锁。
大容量更新锁:允许多个线程将大容量数据并发的插入到同一个表中,在加载的同时,不允许其它进程访问该表。
这些锁之间的相互兼容性,也就是,是否可以同时存在。
| 现有的授权模式 | ||||||
| 请求的模式 | IS | S | U | IX | SIX | X |
| 意向共享 (IS) | 是 | 是 | 是 | 是 | 是 | |
| 共享 (S) | 是 | 是 | 是 | |||
| 更新 (U) | 是 | 是 | ||||
| 意向排他 (IX) | 是 | 是 | ||||
| 意向排他共享 (SIX) | 是 | |||||
| 排他 (X) | ||||||
7.死锁
死锁是指在一组进程中的各个进程均占有不会释放的资源,但因互相申请被其他进程所站用不会释放的资源而处于的一种永久等待状态。
减少死锁的方法大致有一下几种:
按同一顺序访问对象:并发事务按同一顺序访问对象,则发生死锁的可能性会降低。
保持事务简短:尽量不要让一个事务处理过于复杂的读写操作,事务过于复杂,占用资源会增多,处理时间增长,并发执行事物通常会发生死锁。
避免事务中的用户交互:尽量不要在事务中要求用户响应,因为事务持有的任何锁只有在事务提交或回滚后才会释放,等待用户响应的时间,容易导致阻塞或死锁。
减少并发量及占用时间长的数据操作:尽量减少数据库的并发量,减少事务长时间等待。
使用较低的隔离级别:使用较低的隔离级别比使用较高的隔离级别持有共享锁的时间更短。这样就减少了锁争用。注意:先确定事务是否能在较低的隔离级别上运行。
使用基于行版本控制的隔离级别:如果将 READ_COMMITTED_SNAPSHOT 数据库选项设置为 ON,则在已提交读隔离级别下运行的事务在读操作期间将使用行版本控制而不是共享锁。
8.为事务设置隔离级别
所谓事物隔离级别,就是并发事务对同一资源的读取深度层次。分为5种。
read uncommitted:这个隔离级别最低啦,可以读取到一个事务正在处理的数据,但事务还未提交,这种级别的读取叫做脏读。
read committed:这个级别是默认选项,不能脏读,不能读取事务正在处理没有提交的数据,但能修改。
repeatable read:不能读取事务正在处理的数据,也不能修改事务处理数据前的数据。
snapshot:指定事务在开始的时候,就获得了已经提交数据的快照,因此当前事务只能看到事务开始之前对数据所做的修改。
serializable:最高事务隔离级别,只能看到事务处理之前的数据。
语法
set tran isolation level <级别>
示例1:read uncommitted
begin tran
set deadlock_priority low
update A set name='小王1' where id=1 --原数据小王
waitfor delay '0:0:5' --等待5秒执行下面的语句
rollback tran
set tran isolation level read uncommitted
select * from A --读取的数据为正在修改的数据 ,脏读
waitfor delay '0:0:5' --5秒之后数据已经回滚
select * from A --回滚之后的数据
得到 name='小王'。
示例2:read committed
begin tran
update A set name='小王'
waitfor delay '0:0:10' --等待10秒执行下面的语句
rollback tran
set tran isolation level read committed
select * from A --获取不到A,不能脏读
update A set name='小王2' where id=1 --可以修改
waitfor delay '0:0:10' --10秒之后上一个事务已经回滚
select * from A--修改之后的数据,而不是A
得到 name='小王2'。
SQL Server中的事物的更多相关文章
- 再谈SQL Server中日志的的作用
简介 之前我已经写了一个关于SQL Server日志的简单系列文章.本篇文章会进一步挖掘日志背后的一些概念,原理以及作用.如果您没有看过我之前的文章,请参阅: 浅谈SQL Server ...
- SQL Server 中的事务与事务隔离级别以及如何理解脏读, 未提交读,不可重复读和幻读产生的过程和原因
原本打算写有关 SSIS Package 中的事务控制过程的,但是发现很多基本的概念还是需要有 SQL Server 事务和事务的隔离级别做基础铺垫.所以花了点时间,把 SQL Server 数据库中 ...
- SQL Server中的事务与锁
了解事务和锁 事务:保持逻辑数据一致性与可恢复性,必不可少的利器. 锁:多用户访问同一数据库资源时,对访问的先后次序权限管理的一种机制,没有他事务或许将会一塌糊涂,不能保证数据的安全正确读写. 死锁: ...
- 【转】SQL Server中的事务与锁
SQL Server中的事务与锁 了解事务和锁 事务:保持逻辑数据一致性与可恢复性,必不可少的利器. 锁:多用户访问同一数据库资源时,对访问的先后次序权限管理的一种机制,没有他事务或许将会一塌糊涂 ...
- SQL点滴9—SQL Server中的事务处理以及SSIS中的内建事务
原文:SQL点滴9-SQL Server中的事务处理以及SSIS中的内建事务 我们可以把SSIS中的整个package包含在一个事务中,但是如果在package的执行过程中有一个表需要锁定应该怎么处理 ...
- SQL Server中日志
再谈SQL Server中日志的的作用 简介 之前我已经写了一个关于SQL Server日志的简单系列文章.本篇文章会进一步挖掘日志背后的一些概念,原理以及作用.如果您没有看过我之前的文章,请参阅: ...
- SQL Server 中的6种事务隔离级别简单总结
本文出处:http://www.cnblogs.com/wy123/p/7218316.html (保留出处并非什么原创作品权利,本人拙作还远远达不到,仅仅是为了链接到原文,因为后续对可能存在的一些错 ...
- SQL Server中锁与事务隔离级别
SQL Server中的锁分为两类: 共享锁 排它锁 锁的兼容性:事务间锁的相互影响称为锁的兼容性. 锁模式 是否可以持有排它锁 是否可以持有共享锁 已持有排它锁 否 否 已持有共享锁 否 是 SQL ...
- [转载]SQL Server中的事务与锁
了解事务和锁 事务:保持逻辑数据一致性与可恢复性,必不可少的利器. 锁:多用户访问同一数据库资源时,对访问的先后次序权限管理的一种机制,没有他事务或许将会一塌糊涂,不能保证数据的安全正确读写. 死锁: ...
随机推荐
- Development of large-scale site performance optimization method from LiveJournal background
A LiveJournal course of development is a project in the 99 years began in the campus, a few people d ...
- PHP通过ini_set()来设置显示错误信息和执行时间
PHP的 ini_set函数是设置选项中的值,在执行函数后生效,脚本结束的时候,这个设置也失效.不是所有的选项都能被改函数设置的.具体那些值能够设置,可以查看手册中的列表. 就是能够设置php.ini ...
- iOS上架ipa上传问题那些事
iOS上架ipa上传问题那些事 原文: http://www.jianshu.com/p/1e22543285c2 字数513 阅读312 评论0 喜欢1 通过xcode直接打包上传,不会提示你的ip ...
- ubuntu15.10安装搜狗拼音输入法
sudo vim /etc/apt/sources.list.d/ubuntukylin.list(我的默认显示没有这个文件将自动创建) 添加源deb http://archive.ubuntukyl ...
- python之路七
静态方法 通过@staticmethod装饰器即可把其装饰的方法变为一个静态方法,什么是静态方法呢?其实不难理解,普通的方法,可以在实例化后直接调用,并且在方法里可以通过self.调用实例变量或类变量 ...
- 十三. JEB破解三
一.启动环境 JEB 2.0Demo版本启动后出现这样一个界面 当前环境算出的许可证数据 48000000BDEAE192E4CEFC82B34C2AC67F3A85DF5C0E262E421772C ...
- 【转】sed 简明教程
本文转自:http://coolshell.cn/articles/9104.html awk于1977年出生,今年36岁本命年,sed比awk大2-3岁,awk就像林妹妹,sed就是宝玉哥哥了.所以 ...
- HTML5实现网页的全屏切换
使用HTML5提供的JavaScript Api可以实现主流浏览器的全屏和退出全屏操作,封装成进入全屏和退出全屏的函数如下: //进入全屏 function enterFullScreen() { v ...
- SQL入门语句之LIKE、GLOB和LIMIT
一.SQL入门语句之LIKE LIKE用来匹配通配符指定模式的文本值.如果搜索表达式与模式表达式匹配,LIKE 运算符将返回真(true),也就是 1.这里有两个通配符与 LIKE 运算符一起使用,百 ...
- Servlet 生命周期与web容器的关系
servlet生命周期由web容器(如tomcat)管理,初始化一次,直到web容器关闭才会被销毁.1.servlet是单例多线程,每个请求过来容器都会启用一个新线程 2.servlet在容器中保持单 ...