事务中的变量(包括表变量)的操作是不受事务控制的。但是反过来,事务中的变量操作失败,却会导致事务提交失败,这个有点让人郁闷。
下面的脚本演示这个问题。示例演示分拆以逗号分隔的 @ids 中的每个 id, 如果这个 id 是数字(int型),则做后面的处理;如果不是数字(赋值失败,进入CATCH块),则跳过这个id,处理下一个。整个处理在一个事务中进行。
DECLARE
@ids varchar(1000);
SET @ids = '1,a,3,';
BEGIN TRY
BEGIN TRAN;
-- 循环分拆@ids 中以逗号分隔的每个id
WHILE CHARINDEX(',', @ids) > 0
BEGIN
DECLARE
@id int;
BEGIN TRY
-- 获取当前的id
SET @id =LEFT(@ids, CHARINDEX(',', @ids) - 1);
END TRY
BEGIN CATCH
-- 从@ids 中去掉当前的id
SET @ids = STUFF(@ids, 1, CHARINDEX(',', @ids), '');
CONTINUE;
END CATCH
-- 从@ids 中去掉当前的id
SET @ids = STUFF(@ids, 1, CHARINDEX(',', @ids), '');
-- 处理id
RAISERROR('current id: %d', 10, 1, @id) WITH NOWAIT;
END
COMMIT TRAN;
END TRY
BEGIN CATCH
IF XACT_STATE() <> 0
ROLLBACK TRAN;
SELECT
err_line = ERROR_LINE(),
err_message = ERROR_MESSAGE();
END CATCH
这个脚本执行后,输出消息如下:
current id: 1
current id: 3
err_line err_message
----------- -------------------------------------------------------
30 当前事务无法提交,而且无法支持写入日志文件的操作。请回滚该事务。
(1 行受影响)
这个结果表明,@ids 中的所有 id 确实在循环中处理过,但第二个id由于不是数字,所以跳过了。但最终提交事务失败了,因为第二个id不是数字,导致赋值失败,从而导致事务不可提交。
发现这个问题是因为公司在用Service Broker传递业务数据,由于传递的xml数据有问题,导致类型不是期望有类型,从而使处理失败。
个人觉得这个问题有点令人讨厌,按照我的理解,既然不受事务控制,那么它也不应该反过来影响事务,可是结果与理解的不一样,值得注意。
最后补充一下:写这个的重点在于提醒大家,在事务处理中,不要忽略那些看起来与事务无关的处理,它们出错一样会影响事务的最终提交。当然,解决的办法是把这与事务无关的操作放在事务外(不过如果是存储过程嵌套,就不好控制)。另外一个,只要处理可能会在事务中,则出错时都抛出错误,而不试图忽略错误,这样可以解决问题。
分享到:
相关推荐
此代码采用直接给线程变量赋值不需要参数传递
WinCC PRO V16使用C脚本给变量赋值的具体方法
动态给fastreport报表中的变量赋值(因论坛中有人提过这问题)!
回归分析中变量的赋值,讲述关于数学建模中变量赋值的问题
易语言置入变量赋值源码,置入变量赋值
统计软件spss16.0 变量赋值分两组视频教程,如何给变量赋值和分组
主要介绍了springboot 使用yml配置文件给静态变量赋值教程,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
在函数中给C++指针变量赋值,分析了指针变量的特性,并追踪了给指针变量赋值的过程。
给两个整型变量赋值,然后交换两个变量的值,最后输出交换后的变量值。
TIA博途中触摸屏如何通过按钮对变量进行赋值操作?
通过标准的json格式,生成yaml文件,然后再读取yaml文件修改里面的某(多)个变量值,然后再生成新的json,json格式前后都一样,就是为了修改里面的某些变量值,所以用yaml作为中间桥梁
数控宏程序变量赋值试题[参照].pdf
Qt中执行sql语句,当需要变量存取从数据库中获取的值,首先取出一行数据,然后按列将数据分别赋给变量
Python是动态类型语言,也就是说不需要预先声明变量类型,变量的类型和值在赋值那一刻被初始化,下面详细介绍了Python的变量赋值问题,一起来学习学习吧。 我们先看一下如下代码: c = {} def foo(): f = dict(zip...
sql*plus 定义变量,变量赋值,输出到文件;简单
易语言源码易语言置入变量赋值源码.rar 易语言源码易语言置入变量赋值源码.rar 易语言源码易语言置入变量赋值源码.rar 易语言源码易语言置入变量赋值源码.rar 易语言源码易语言置入变量赋值源码.rar 易语言源码...
1、类定义中不能进行初始化,因为头文件中类的定义只是一个声明,并没有分配真正空间,因此变量是不存在的,因此是不能赋值的。 2、const 定义的变量是不能赋值 这可如何是好,声明中不能赋值,声明完还不能赋值。又...
C++中,全局变量只能声明、初始化,而不能赋值 也就是说,下面这样是不被允许的: #include using namespace std; int a; a = 2; int main() { return 0; } 错误提示是: C++ requires a type specifier for all...
一、变量的定义 mysql中变量定义用declare来定义一局部变量,该变量的使用范围只能在begin…end 块中使用,变量必须定义在复合语句的开头,并且是在其它语句之前,也可以同时申明多个变量,如果需要,可以使用default...
《变量与赋值》教案.pdf