Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements
Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements
开始想写一个过程,根据一个项目的数据库的一个表的导数据到另一个数据库中去,本来在本地测试时蛮好的,但是将过程升级到生产服务器之后运行之后,根据下面类似的错误信息发现是生产服务器上引用的数据库名不对。
Msg 208, Level 16, State 1, Procedure test_sp, Line 10
Invalid object name 'test.dbo.col1'.
Msg 266, Level 16, State 2, Procedure test_sp, Line 10
Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 0, current count = 1
出现了这个错之后就去查了下需要插入的表,发现锁表了,所以猜测是不是刚刚运行的过程的事务没有回滚(或提交)。就关闭当前查询窗口,出现如下信息证实了猜测:
但是过程中的TRY CATCH
语句块中已经写有ROLLBACK了。此时,不得不怀疑是不是自己写的TRY CATCH
有问题,首先在过程中添加SELECT 1/0
,对于这一错误ROLLBACK是起作用的。后来就去MSDN看TRY CATCH
帮助文档,发现有这么一段说明:
这个完全符合我遇到的情况,所以原来就是引用表的数据库名写错,造成致命性错误,使得CATCH
捕捉不到异常,所以事务没能ROLLBACK。
演示
我就改写我的过程来演示遇到的问题和解决这个问题的方案。T1
表中只有3条数据
CREATE PROCEDURE [dbo].[test_sp] AS
BEGIN TRY
BEGIN TRAN
SET NOCOUNT ON;
INSERT INTO T1( col1, col2 )VALUES( 3,3);
SELECT * FROM T1;
SELECT * FROM [AdventureWorks2012].[dbo].[T2]
COMMIT TRAN;
END TRY
BEGIN CATCH
ROLLBACK TRAN;
THROW;
END CATCH
在查询1窗口执行test_sp
过程
EXEC test_sp
--连接上执行的 BEGIN TRANSACTION 语句的数目
SELECT @@TRANCOUNT AS Trancount


如果想关闭当前查询1窗口,弹出信息:

在查询2窗口查询T1
和[AdventureWorks2012].[dbo].[T2]
--查询T1
SELECT * FROM T1;
表T1
一直被查询1的事务占用:

--查询T2
SELECT * FROM [AdventureWorks2012].[dbo].[T2]
T2
没有创建:

解决方案
首先使用KILL
命令将查询1的连接给断开,然后在test_sp
中设置XACT_ABORT
为ON。如果XACT_ABORT
为ON时,如果执行 Transact-SQL 语句产生运行时错误,则整个事务将终止并回滚;为 OFF 时,有时只回滚产生错误的 Transact-SQL 语句,而事务将继续进行处理。 如果错误很严重,那么即使 SET XACT_ABORT 为 OFF,也可能回滚整个事务。 OFF 是默认设置。
SET XACT_ABORT ON;
我们在查询1窗口中重新运行,顺带尝试关闭窗口:
EXEC test_sp
SELECT @@TRANCOUNT AS Trancount
--查询T1
SELECT * FROM T1;



@@TRANCOUNT
为0,T1
表还是只有3条纪录,说明事务顺利的终止并且回滚了。
我们在AdventureWorks2012
数据库中创建t2
CREATE TABLE t2 (col1 int)
在查询1中先运行一遍将第4条数据插入,再运行第二遍。
EXEC test_sp

由于主键约束,抛出异常,我们可以检查当前连接的事务连接数也是0:
SELECT @@TRANCOUNT AS Trancount

结论
设置XACT_ABORT
为ON时,即使过程中没有TRY CATCH
,如果语句导致任何异常才会发生回滚。所以我们要灵活使用XACT_ABORT
,如果使用TRY CATCH
能够捕捉所有需要解决的错误时,我们就不必开启XACT_ABORT
,只有错误比较严重时才考虑XACT_ABORT
为ON。
所以,我应该滚回去修改引用的数据库名就好了。
参考:
http://www.cnblogs.com/chenxizhang/archive/2008/07/29/1255737.html
https://technet.microsoft.com/zh-cn/library/ms164086.aspx
https://msdn.microsoft.com/zh-cn/library/ms188792(v=sql.120).aspx
https://www.mssqltips.com/sqlservertip/4018/sql-server-transaction-count-after-execute-indicates-a-mismatching-number-of-begin-and-commit-statements/
返回顶部
Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements的更多相关文章
- EF非常见错误:EXECUTE 后的事务计数指示 BEGIN 和 COMMIT 语句的数目不匹配
EF非常见错误:EXECUTE 后的事务计数指示 BEGIN 和 COMMIT 语句的数目不匹配 问题原因: 两个表A\B之间存在外键关系,当插入表A的时候,A的外键B在B表中不存在可以引起这个问题: ...
- EXECUTE 后的事务计数指示 BEGIN 和 COMMIT 语句的数目不匹配
代码中的事务包含了存储过程中的事务.
- System.Data.SqlClient.SqlException (0x80131904): EXECUTE 后的事务计数指示 BEGIN 和 COMMIT 语句的数目不匹配。上一计数 = 1,当前计数 = 0。 EXECUTE 后的事务计数指示 BEGIN 和 COMMIT 语句的数目不匹配。上一计数 = 1,当前计数 = 0。
EF使用ExecuteSqlCommand(db.Database.ExecuteSqlCommand("exec proc_DeleteCaseInfo_Output @caseID&qu ...
- EXECUTE 后的事务计数指示缺少了 COMMIT 或 ROLLBACK TRANSACTION 语句。上一计数 = 1,当前计数 = 2
理解这一句话: 一个begin tran会增加一个事务计数器,要有相同数量的commit与之对应,而rollback可以回滚全部计数器 这个错误一般是出现在嵌套事务中. 测试环境 sql 2008 例 ...
- Nested transactions in stored procedure of SQLServer
question: if the nested transaction encountered an exception, then rollbacked. How about the outer t ...
- Sqlserver的Transaction做Rollback的时候要小心(转载)
仔细研究了下,发现sql server里面的explicit transaction(显示事务)还是有点复杂的.以下是有些总结: Commit transaction 会提交所有嵌套的transact ...
- [转]sql server transaction
本文转自: http://www.2cto.com/database/201208/146734.html sql事务(Transaction)用法介绍及回滚实例 事务(Transaction)是 ...
- SQL Server 全局变量
SQL Server中所有全局变量都使用两个@符号作为前缀 --1.@@error 最后一个T-SQL错误的错误号(目的是或得违反约束的错误号) insert into Subject values( ...
- SQL Server 中的嵌套事务与@@TranCount(转)
在处理事务的时候,一般都用RollBack Transaction来回滚,但是如果在嵌套事务中这样使用的话,就会出现错误. 在SqlServer里,嵌套事务的层次是由@@TranCount全局变量反映 ...
随机推荐
- Android ExpandableListView的使用详解
ExpandableListView(可扩展的ListView) ExpandableListVivew是ListView的子类,它在普通ListView的基础上进行了扩展,它把应用中的列表项分为几组 ...
- java编码终极探秘
首先要明白,java中string字符串都是unicode码保存的,只不过显示的时候会根据一定的规则,比如GBK或者是UTF-8去对照表中查找进行显示. 之所以会乱码就是因为使用错了编码方式. 数据是 ...
- 170925_1 Python socket 创建TCP的服务器端和客户端
[Python版本]3.6 [遇到的问题] 客户端和服务器端都遇到:TypeError: a bytes-like object is required, not 'str' [解决方案] 参考:ht ...
- PHP采用301跳转方式防CC拦截
PHP采用301跳转方式防CC拦截 降低CC攻击的效果 <?php empty($_SERVER['HTTP_VIA']) or exit('Access Denied'); $second ...
- CAD在网页中绘制批注
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 3 ...
- ubuntu14.04禁用USB外存储设备
ubuntu 14.04中禁用usb外存储设备: 在网上找了很多方法,大概都是下面的命令,而实际测试的时候没有什么作用. gsettings set org.gnome.desktop.media-h ...
- python学习笔记--深拷贝与浅拷贝的区别
首先我们来讲讲我们python中的可变对象和不可变对象: 可变对象:该对象指向内存中的值是可以改变的.实际上是其所指的值直接发生改变,而不是发生复制,或者开辟一个新的地址空间.例如:列表list,字典 ...
- BZOJ 1601 USACO 2008 Oct. 灌水
[Description] Farmer John已经决定把水灌到他的n(1<=n<=300)块农田,农田被数字1到n标记.把一块土地进行灌水有两种方法,从其他农田饮水,或者这块土地建造水 ...
- 手动部署tidb(二进制包)集群
环境准备 系统:centos7.2 用户:root 主机配置ntp时间同步 主机配置ssh互信 3节点: hostname@ip 部署组件 tidb1@10.70.249.24 PD,TiKV,TiD ...
- CDOJ 888 Absurdistan Roads
Absurdistan Roads Time Limit: 5678/3456MS (Java/Others) Memory Limit: 65432/65432KB (Java/Others ...