服务器无法继续该事务 3400000006 错误原因--JAVA调用SQLSERVER存储过程时过程发生异常内部事务未

当JAVA调用SQLSERVER存储过程时,如果存储过程内部发生类型转换异常且未正确处理事务,会导致进程中断且事务未提交,进而影响后续交易。此问题可能因存储过程内部开启的事务未提交,使得JAVA事务也无法提交,尤其是在连接池中,未提交事务的连接会被重复使用,引发"无法提交事务"的异常。解决方案是避免在存储过程中定义事务,让JDBC管理事务。
摘要由CSDN通过智能技术生成
               

    通过JAVA调用SQLSERVER存储过程时,存储过程内部发生了类型转换异常,在类型转换异常发生之前已经将事务打开了,并且在类型转换那一行没有采用像如下错误处理:

    if @@error<>0 then

        goto err

    end

    导致了过程在发生异常的时候直接中断返回JAVA,此时过程内部的事务并没有提交,根据MICROSOFT的文档如果存储过程内部有事务并且事务没有提交,那么JAVA的事务也不会提交,JAVA的事务须在过程事务提交以后才会被提交。当前系统也采用了连接池,此时JAVA容器直接将没有提交事务的连接再次放回连接池中,这样就影响到了后续的交易,如果后续交易使用到了该连接就会报“无法提交事务”的异常,以下是我在博客园(http://kb.cnblogs.com/b/237188/)看到的一篇文章,对这样的错误讲得非常清楚:

           有个客户跟我说,他们把weblogic从923升级到923以后,总是提示failed to resume transaction的。当时没有看到任何信息,以为跟JTA超时有关,让客户把JTA timeout加大,同时把下面的设置加入jdbc-config.xml中。客户反馈过来说:还是不行。 :( 

    <keep-xa-conn-till-tx-complete>true</keep-xa-conn-till-tx-complete>
    <rollback-local-tx-upon-conn-close>true</rollback-local-tx-upon-conn-close>

        比较郁闷,后来想想,客户的jdbc是使用non-XA的driver, 同时将emulate-2pc设为了true,上面连个参数是针对XA的,测试没有效果应该是正常的。:)  客户把具体错误信息给我发了过来,如下:

####<2008-10-27 上午10时35分28秒 CST> <Error> <JDBC> <SZSEWEB-YSXAPP> <appServer11> <[ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <> <1225074928234> <BEA-001112> <Test "SELECT 1" set up for pool "szseWebDataSource" failed with exception: "java.sql.SQLException: [BEA][SQLServer JDBC Driver][SQLServer]服务器无法继续执行该事务。说明: 3c00000047。".> 

        奇怪了,对于non-XA的connection, weblogic做测试的时候,应该是不会其transaction的,而且是直接拿底层的物理connection来做个select,怎么会有transaction resume呢? 是不是底层物理连接出现了问题? 跟客户沟通了一下,大概了解了他们的应用:通过jdbc调用SQL Server的stored procedure,而stored procedure中会起自己的transaction。 Tx中的操作分两种类型:
1:业务简单,数据量大
2:数据不大,但业务比较复杂
总之,TX中的SQL执行时间比较长。

        开始怀疑跟客户的stored procedure有关,建议他先去掉里面的TX,果然奏效。因为transaction一直是我比较模糊的董东,也不敢跟客户说:你不能这么写,这么写是不可以的。毕竟自己底气不足啊。不是很清楚jdbc connection的auto commit提交的到底是哪个事务,是driver的tx,还是stored procedure里的tx。应该是前者吧。花了一上午,自己搭了个测试环境,终于复现了这个问题:

存储过程:

1  create proc dbo.TestProc
2  as
3  begin transaction
4      waitfor delay  ' 00:02:00 '
5      insert into dbo.TestT_1 values( ' test ' )
6  commit


JDBC 代码:

  1  package  com.bea.cs.test.jdbc;
  2 
  3  import  com.bea.cs.test.utils.JNDIRetriver;
  4  import  java.sql. * ;
  5  import  java.io. * ;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值