SqlCommand使用有rollback transaction的事务报异常

问题描述

数据库SqlServer2008,创建一个存储过程createproceduresp_test1(@idint)asbegintransactionif@id=1beginrollbacktransactionendelsebegincommittransactionend

//调试代码publicboolTestProc(intid){try{//SqlCommandcmd=newSqlCommand("sp_test1");//cmd.CommandType=CommandType.StoredProcedure;SqlCommandcmd=newSqlCommand("execsp_test1@id");cmd.CommandType=CommandType.Text;cmd.Parameters.Add("@id",id);introwCount=SqlUtil.ExecuteNonQuery(cmd);returnrowCount>0;}catch(Exceptione){Console.WriteLine(e);}returnfalse;}

无论是使用CommandType.StoredProcedure还是CommandType.Text;只要当传入的参数是1时,都会抛出异常,也就是只要存储过程中执行到rollback时,就会抛出异常(我就是实际调用一个比较复杂的储存过程,然后一直抛出异常,在存储过程中增加了无数print语句跟踪,才觉得是这个rollback问题,创建这个存储过程测试的)当然,直接使用SqlServerManagementStudio执行execErpCore_Server.dbo.sp_test11,是成功执行的,并且没有异常信息异常信息EXECUTE后的事务计数指示BEGIN和COMMIT语句的数目不匹配。上一计数=1,当前计数=0。不知道有人碰到过这种情况没有?网上搜了一堆,基本没有看到有人提到过这个情况的

解决方案

本帖最后由 jestymat 于 2016-05-25 18:11:32 编辑
解决方案二:
begintran跟“committrans”/“rolltans”的个数不匹配。恐怕你的“无数print语句跟踪”也是很不准确、有一个漏网的吧?你确定你写的那个简单的demo一定会产生异常吗?在sqlserver高版本上也产生异常吗?如果真的是这样,你可以把这个简单的测试拿给微软看,它们的sqlserver2008还真的有bug呢!不过话说回来了,你为什么要在存储过程中要使用commit、roolback呢?当sqlserver执行一条命令时,它默认地本身就启动了一个事务,并不需要你再写一个begintran语句。你的存储过程要回滚数据修改语句,应该写raiserror(...)命令。我估计你是不知道如何使用t-sql语句来正规地抛出异常,只知道“正常结束”存储过程的语句,所以才画蛇添足地写了好几个事务语句。
解决方案三:
引用1楼sp1234的回复:

begintran跟“committrans”/“rolltans”的个数不匹配。恐怕你的“无数print语句跟踪”也是很不准确、有一个漏网的吧?你确定你写的那个简单的demo一定会产生异常吗?在sqlserver高版本上也产生异常吗?如果真的是这样,你可以把这个简单的测试拿给微软看,它们的sqlserver2008还真的有bug呢!不过话说回来了,你为什么要在存储过程中要使用commit、roolback呢?当sqlserver执行一条命令时,它默认地本身就启动了一个事务,并不需要你再写一个begintran语句。你的存储过程要回滚数据修改语句,应该写raiserror(...)命令。我估计你是不知道如何使用t-sql语句来正规地抛出异常,只知道“正常结束”存储过程的语句,所以才画蛇添足地写了好几个事务语句。

我敢确定你有没有仔细看帖子首先,这个并不是sqlserver2008的错误,储存过程在sqlserver2008中执行是不会报错的,只是在使用.NET调用的时候才会抛出异常其次,写这么简单的一个事务例子就是方便测试,难道我需要拿出实际当中碰到的,近百行sql,修改近10张表的存储过程,并且给出所有的表结构,以及可以供大家测试的数据,让大家测试吗?
解决方案四:
找到原因了,是封装的SqlUtil原因,使用原生的单个命令方法就不会抛出异常using(SqlConnectionconn=newSqlConnection(s)){conn.Open();SqlCommandcmd=newSqlCommand("sp_test1");cmd.CommandType=CommandType.StoredProcedure;//SqlCommandcmd=newSqlCommand("execErpCore_Server.dbo.sp_test1@id");//cmd.CommandType=CommandType.Text;cmd.Parameters.Add("@id",id);cmd.Connection=conn;introwCount=cmd.ExecuteNonQuery();}

封装的SqlUtil默认开启了事务,并且执行后提交事务如果换成原生的方法,则是introwCount=0;using(SqlConnectionconn=newSqlConnection(s)){conn.Open();using(SqlTransactiontran=conn.BeginTransaction()){SqlCommandcmd=newSqlCommand("ErpCore_Server.dbo.sp_test1");cmd.CommandType=CommandType.StoredProcedure;cmd.Parameters.Add("@id",id);cmd.Connection=conn;cmd.Transaction=tran;rowCount=cmd.ExecuteNonQuery();//执行到此处的时候,有可能会抛出异常tran.Commit();}}returnrowCount>0;

那么新的问题来了,为什么当存储过程中,执行了rollbacktransaction时,就抛出异常,而当存储过程执行了committransaction时,这个语句就不会抛出异常
解决方案五:
//调试代码publicboolTestProc(intid){try{//SqlCommandcmd=newSqlCommand("sp_test1");//cmd.CommandType=CommandType.StoredProcedure;SqlCommandcmd=newwww.60400.comSqlCommand("execsp_test1@id");cmd.CommandType=CommandType.Text;cmd.Parameters.Add("@id",id);introwCount=SqlUtil.ExecuteNonQuery(cmd);returnrowCount>0;}catch(Exceptione){Console.WriteLine(e);}returnfalse;

时间: 2024-11-03 22:18:57

SqlCommand使用有rollback transaction的事务报异常的相关文章

AUTONOMOUS TRANSACTION(自治事务)的介绍

    在基于低版本的ORACLE做一些项目的过程中,有时会遇到一些头疼的问题.,比如想在执行当前一个由多个DML组成的transaction(事务)时,为每一步DML记录一些信息到跟踪表中,由于事务的原子性,这些跟踪信息的提交将决定于主事务的commit或rollback. 这样一来写程序的难度就增大了, 程序员不得不把这些跟踪信息记录到类似数组的结构中,然后在主事务结束后把它们存入跟踪表.哎,真是麻烦! 有没有一个简单的方法解决类似问题呢? ORACLE8i的AUTONOMOUS TRANS

java 连接异常-java 启动jdbc 事务报错 嵌套异常

问题描述 java 启动jdbc 事务报错 嵌套异常 org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException: Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC

关于SQL Server 事务、异常和游标详解(1/3)

本教程来说一下关于SQL Server 事务.异常和游标的事情下面来看教程,希望对你有帮助. 1. 事务的特点         事务有若干条T-SQL指令组成,并且所有的指令昨晚一个整体提交给数据库教程系统,执行时,这组指令要么全部执行完成,要么全部取消.因此,事务是一个不可分割的逻辑单元.           事务有4个属性:原子性(Atomicity).一致性(Consistency).隔离性(Isolation)以及持久性(Durability),也称作事务的ACID属性.        

java c3p0时不时的报异常,谁碰到过

问题描述 java c3p0时不时的报异常,谁碰到过 ** BEGIN NESTED EXCEPTION ** java.net.SocketExceptionMESSAGE: Socket input is already shutdown STACKTRACE: java.net.SocketException: Socket input is already shutdown at java.net.Socket.shutdownInput(Socket.java:1361) at com

process-Widget启动报异常。请求解决

问题描述 Widget启动报异常.请求解决 Unable to launch app or broadcast Intent process is bad act=android.appwidget.action.APPWIDGET_ENABLED 怎么回事啊!!! 开始还好好的,后来不晓得怎么了,装widget一直报这个错,不晓得抽什么风, 网上说神马卸掉重装,卸掉关机重启重装,统统都不行.... 解决方案 http://stackoverflow.com/questions/3253676/

tomcat启动的问题,报异常

问题描述 tomcat启动的问题,报异常 解决方案 和tomcat没关系.是你web.xml中的配置的servlet加载的时候报错了 解决方案二: 采用flex+struts+spring+hibernate框架,启动tomcat出现异常,寻求解决方法中..... 严重: StandardWrapper.Throwablejava.lang.NullPointerException?at flex.management.BaseControl.getObjectName(BaseControl.

myeclipse配置了weblogic,启动服务报异常

问题描述 myeclipse配置了weblogic,启动服务报异常 1C 解决方案 认证没有通过,估计是myeclipse配置weblogic,忘了设置 解决方案二: weblogic用户名密码不对~

使用osgi api启动osgi时,用java -jar命令运行报异常,用eclipse运行正常

问题描述 使用osgi api启动osgi时,用java -jar命令运行报异常,用eclipse运行正常 我使用osgi的api写了osgi框架的启动程序,然后使用java -jar 命令运行这个jar包报空指针异常,我在eclipse中运行一切正常,请问这是为什么呀

java-myeclipse10配置jrebel6因为改动电脑日期报异常

问题描述 myeclipse10配置jrebel6因为改动电脑日期报异常 运行环境:myeclipse10配置jrebel6 问题原因:在myeclise10的tomcat7的jdk下Optional java VM arguments配置上jrebel后加入,在电脑日期是今天2015.10.21下启动tomcat,能正常启动,但是假如电脑日期把今天改为2015.10.06启动tomcat就会抛出一个异常: if (!fromStart && !toEnd) { if (m.compare