SQL Server——事务嵌套(未完工)
http://www.cnblogs.com/Kymo/archive/2008/05/14/1194161.html
先看一下SQL Server Online Help相关的说明
- Begin Transaction:标记一个显式本地事务的起始点。BEGIN TRANSACTION 使 @@TRANCOUNT 按 1 递增。
- Rollback Transaction: 将显式事务或隐性事务回滚到事务的起点或事务内的某个保存点。(嵌套事务时,该语句将所有内层事务回滚到最外面的 BEGIN TRANSACTION 语句。无论在哪种情况下,ROLLBACK TRANSACTION 都将 @@TRANCOUNT 系统函数减小为 0。ROLLBACK TRANSACTION savepoint_name 不减小 @@TRANCOUNT。)
- Commit Transaction:标志一个成功的隐性事务或显式事务的结束。如果 @@TRANCOUNT 为 1,COMMIT TRANSACTION 使得自从事务开始以来所执行的所有数据修改成为数据库的永久部分,释放事务所占用的资源,并将 @@TRANCOUNT 减少到 0。如果 @@TRANCOUNT 大于 1,则 COMMIT TRANSACTION 使 @@TRANCOUNT 按 1 递减并且事务将保持活动状态。
下面用代码进行解释,代码是根据Online Help Commit Transaction一节的代码修改而成,首先建立一个Table,然后开始三个Trasaction,中间人为触发一些错误,然后观察运行结果。
--Bad code2
USE NORTHWIND;3
--Create test table4
IF Object_id(N'TestTran',N'U') IS NOT NULL5
DROP TABLE TESTTRAN;6

7
CREATE TABLE TESTTRAN (8
COLA INT PRIMARY KEY,9
COLB CHAR(3));10

11
--Variable for keeping @@ERROR12
DECLARE @_Error INT;13
SET @_Error = 0;14

15
--Begin 3 nested transaction16
BEGIN TRANSACTION OUTERTRAN;17
BEGIN TRANSACTION INNER1;18
BEGIN TRANSACTION INNER2;19

20
INSERT INTO TESTTRAN VALUES (3,'ccc');--Inner221

22
RAISERROR('Inner2 error', 16, 1)23
IF @@ERROR = 024
COMMIT TRANSACTION INNER2;25
ELSE26
ROLLBACK TRANSACTION ;27
28
INSERT INTO TESTTRAN VALUES (2,'bbb');--Inner129

30
IF @@ERROR = 031
COMMIT TRANSACTION INNER1;32
ELSE33
ROLLBACK TRANSACTION ;34
35
INSERT INTO TESTTRAN VALUES (1,'aaa');--OuterTran36

37
--RAISERROR ('OuterTran error',16,1)38
39
IF @@ERROR = 040
COMMIT TRANSACTION OuterTran;41
ELSE42
ROLLBACK TRANSACTION; 43

44
SELECT * FROM TESTTRAN (NOLOCK);45
SELECT @@Trancount;上述代码当内层事务发生错误时,并不能正常Rollback,因为Rollback把@@Trancount变成了0,所以后面的Commit语句就找不到对应的Transaction了。解决问题的关键就是Rollback时要判断@@Trancount,当@@Trancount等于1时进行Rollback进行回滚,否则执行Commit把@@Trancount-1,同时把@@Error传到外层事务交给外层事务处理。微软的原文是没有问题的,但是这种情况比较简单,我们一眼就能看出哪个是内层事务,哪个是外层事务,一共嵌套了几层,如果是SP调用呢?你不知道你的SP会被谁调用,也不知道会被嵌套几层。
下面看一下怎么处理内层事务的错误(何时Rollback, Commit及错误的传递)
2
USE NORTHWIND;3

4
--Create test table5
IF Object_id(N'TestTran',N'U') IS NOT NULL6
DROP TABLE TE
STTRAN;7

8
CREATE TABLE TESTTRAN (9
COLA INT PRIMARY KEY,10
COLB CHAR(3));11

12
--Variable for keeping @@ERROR13
DECLARE @_Error INT;14
SET @_Error = 0;15

16
--Begin 3 nested transaction17
BEGIN TRANSACTION OUTERTRAN;18
BEGIN TRANSACTION INNER1;19
BEGIN TRANSACTION INNER2;20

21
INSERT INTO TESTTRAN VALUES (3,'ccc');--Inner222

23
--raiserror('Inner2 error', 16, 1)24
SET @_Error = @@ERROR 25
IF @_Error = 026
COMMIT TRAN INNER2;27
ELSE28
IF @@TRANCOUNT > 129
COMMIT TRANSACTION INNER2;30
ELSE31
ROLLBACK TRANSACTION INNER2;32
33
INSERT INTO TESTTRAN VALUES (2,'bbb');--Inner134

35
IF @_Error = 036
SET @_Error = @@ERROR 37
IF @_Error = 038
COMMIT TRAN INNER1;39
ELSE40
IF @@TRANCOUNT > 141
COMMIT TRANSACTION INNER1;42
ELSE43
ROLLBACK TRANSACTION INNER1;44
45
INSERT INTO TESTTRAN VALUES (1,'aaa');--OuterTran46

47
RAISERROR ('OuterTran error',16,1)48

49
-- rollback transaction OuterTran50
SET @_Error = @_Error + @@ERROR51
52
IF @_Error = 053
COMMIT TRAN OUTERTRAN;54
ELSE55
IF @@TRANCOUNT > 156
COMMIT TRANSACTION;57
ELSE58
ROLLBACK TRANSACTION OUTERTRAN; 59

60
SELECT * FROM TESTTRAN (NOLOCK)SQL Server——事务嵌套(未完工)的更多相关文章
- SQL Server 事务嵌套
示例代码: DECLARE @TranCounter INT; SET @TranCounter = @@TRANCOUNT; -- Procedure called when there is -- ...
- 人人都是 DBA(VI)SQL Server 事务日志
SQL Server 的数据库引擎通过事务服务(Transaction Services)提供事务的 ACID 属性支持.ACID 属性包括: 原子性(Atomicity) 一致性(Consisten ...
- SQL Server事务的隔离级别
SQL Server事务的隔离级别 ########## 数据库中数据的一致性 ########## 针对并发事务出现的数据不一致性,提出了4个级别的解决方法: 隔离级别 第一类丢失更新 脏读 ...
- Sql Server 事务隔离级别的查看及更改
根据自身 Sql Server 的情况来自定义 事务隔离级别,将会更加的满足需求,或提升性能.例如,对于逻辑简单的 Sql Server,完全可以使用 read uncommitted 模式,来减少死 ...
- 【SqlServer系列】浅谈SQL Server事务与锁(上篇)
一 概述 在数据库方面,对于非DBA的程序员来说,事务与锁是一大难点,针对该难点,本篇文章视图采用图文的方式来与大家一起探讨. “浅谈SQL Server 事务与锁”这个专题共分两篇,上篇主讲事务及 ...
- 理解Sql Server 事务隔离层级(Transaction Isolation Level)
关于Sql Server 事务隔离级别,百度百科是这样描述的 隔离级别:一个事务必须与由其他事务进行的资源或数据更改相隔离的程度.隔离级别从允许的并发副作用(例如,脏读或虚拟读取)的角度进行描述. 隔 ...
- SQL SERVER 事务和锁
内容皆整理自网络 一.事务 作者:郭无心链接:https://www.zhihu.com/question/31346392/answer/59815366来源:知乎著作权归作者所有.商业转载请联系作 ...
- SQL Server 事务复制爬坑记
SQL Server 复制功能折腾了好几天了,现特将其配置过程以及其间遇到的问题记录下来,以备日后查阅.同时,也让“同道”同学们少走不必要的弯路.如果有不对之处,欢迎大家指正,欢迎沟通交流. 一.复制 ...
- 为什么说JAVA中要慎重使用继承 C# 语言历史版本特性(C# 1.0到C# 8.0汇总) SQL Server事务 事务日志 SQL Server 锁详解 软件架构之 23种设计模式 Oracle与Sqlserver:Order by NULL值介绍 asp.net MVC漏油配置总结
为什么说JAVA中要慎重使用继承 这篇文章的主题并非鼓励不使用继承,而是仅从使用继承带来的问题出发,讨论继承机制不太好的地方,从而在使用时慎重选择,避开可能遇到的坑. JAVA中使用到继承就会有两 ...
随机推荐
- Java -- 利用反射 操作任意数组,包括对象数组 和 基本数据类型的数组
items为任意数组
- QT paintevent 事件, update()槽函数
一界面重载函数 使用方法: 1在头文件里定义函数 protected: void paintEvent(QPaintEvent *event); 2 在CPP内直接重载 void ---------- ...
- mini6410基于linux2.6.36内核通过NFS启动根文件系统总结(四制作根文件系统及通过NFS挂载文件系统)
http://blog.csdn.net/yinjiabin/article/details/7489563 根文件系统一般包括: 1)基本的文件系统结构,包含一些必须的目录,比如:/dev,/pro ...
- Xcode rename failed(修改类名失败)的解决办法
1.前往文件夹~/Library/Developer/Xcode 2.删除Xcode文件夹下的DerivedData 3.等项目加载完成之后,即可rename
- review16
java.lang包中的Math类包含许多用来进行科学计算的方法,这些方法可以直接通过类名调用. Math类中还有两个静态常量E和PI,分别表示自然对数和圆周率. 以下是Math类的常用方法 pulb ...
- ODPS中的TaskContext类里面的write函数
ODPS中的TaskContext类有几个write函数 write(Record record)用来输出到默认输出表 write(Record record, String label)用来输出的l ...
- DecimalFormat数据格式函数
DecimalFormat数据格式函数 class FormatDemo2{ public void format(String pattern, double value) { DecimalFor ...
- java:IO:file 类
刷某一目录下的所有文件夹/文件 public class FileDemo2 { public static void main(String args[]) { File file = new Fi ...
- React native 开发工具 VSCode
1.VSCODE下载地址:先下载VSCode软件 2.代码提示功能: 打开 VSCode ,然后 按住键盘 command+p,然后在vscode上面输入框 输入: "ext install ...
- Git_学习_01_ git 安装与配置
参考:windows下Git BASH安装 二.参考资料 1. windows下Git BASH安装