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中使用到继承就会有两 ...
随机推荐
- PAT1030. Travel Plan (30)
#include <iostream> #include <limits> #include <vector> using namespace std; int n ...
- makefile下$(wildcard $^),$^,$@,$?,$<,$(@D),$(@F) 含义
makefile下$(wildcard $^),$^,$@,$?,$<,$(@D),$(@F)代表的不同含义 $(filter-out $(PHONY) $(wildcard $^),$^) 常 ...
- iframe标签的子父页面调用函数和属性
在使用iframe标签时,总想通过子页面调用父页面的一些方法和属性.今天终于发现了. 1在父页面写一个函数 //让子页面来调用此方法,控制导航栏 function childfunc(){ alert ...
- redis 按空间范围查询点位
GEORADIUS GEORADIUS key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [ASC| ...
- devstack apache2/keystone 没有启动
在devstack中./rejoin-stack.sh 发现apache2/keystone 没有启动 单单手动启动apach2服务之后keystone并没有启动 sudo service apach ...
- FilterDispatcher处理流程
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter 前身是:org.apache.struts2.dispatc ...
- codeigniter教程:Codeigniter出现Unable to connect to your databas
Codeigniter出现A Database Error Occurred错误 下午把项目构建到服务器上的时候,codeigniter竟然出现了 a database error occurred ...
- linux下的第一个C程序及其编译方法
#include <stdio.h> #include <stdlib.h> int main(int argc, char ** argv) { printf(& ...
- poj3171 Cleaning Shifts[DP]
https://vjudge.net/problem/POJ-3171.(有价值的区间全覆盖问题) (lyd例题)朴素DP很好想,$f[i]$表示将右端点从小到大排序后从$L$(要求覆盖的大区间)到第 ...
- [转]【技术心得】Last-Modified,Etag,Expire区别
Last-Modified 是什么 Last-Modified 是 HttpHeader 中的资源的最后修改时间,如果带有 Last-Modified ,下一次发送 Http 请求时,将会发生带 If ...