Jdbc执行存储过程报数据库事务无法执行的异常

Jdbc执行存储过程报数据库事务无法执行的异常

环境:

Eclipse+Jdk1.7+spring-jdbc-3.0.7+同版本的jdbctemplate+Sqlserver 2012

问题:

一个小接口采用jdbctemplate进行对sqlserver的存储过程操作,一般过程执行没问题,但个别存储过程第一次可以执行,第二次再执行就异常;

原因参考:

https://blog.csdn.net/fenglibing/article/details/5160044

原因简要总结:

    每次调用这个存储过程时,比如方法名为updateAllAttas(),下次执行select或其他dao操作会报数据库事务异常,这是由于jdbc的事务同sqlserver存储过程内部的事务发生冲突导致的,一般情况下如果sqlserver的事务中的代码执行时间过长的话,就会产生这种异常报错;每次执行updateAllAttas时,当前connection会产生问题,在方法执行后会被放入连接池,下次jdbc执行dao操作时,可能会从连接池中取出这个有问题的连接来执行dao操作,所以会报异常;解决方法就是:

1:存储过程中的BEGIN TRANSACTION,COMMIT TRANSACTION删除掉,存储过程中不采用事务机制,事务仅仅在jdbc中控制;

2java中每次执行完updateAllAttas这个方法后,释放掉这个connection;那么下次dao操作时,由于连接池中没有这个有问题的连接了,所以下次可以正常执行dao操作。

 方法1由于要修改存储过程,取消事务,当其他系统调用这个存储过程时,由于取消了事务会带来风险。所以采用方法2.将下面这个方法放到dao层类中,

    public void releaseConnection(){

          new ConnectionHolder(DataSourceUtils.getConnection(jdbcTemplateBASE.getDataSource())).released();

//释放连接,采用新连接

     }

因为是采用jdbctemplate来进行dao操作的,上面方法中jdbctemplateBASE就是由spring管理的jdbctemplate对象;

在每次执行完updateAllAttas这个方法后,再调用releaseConnection这个方法即可;

         注意,spring的jdbc的jar包中有好几个类似可以释放连接的方法,经调试,上述ConnectionHolder的released方法有效;其他如DataSourceUtils.releaseConnection(con,datasource)也有释放连接的方法,但是采用这个方法不能解决上述问题

转载于:https://www.cnblogs.com/tapt/p/8796708.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JDBC是Java数据库连接的缩写,它是一组用于操作数据库的Java API。JDBC提供了一种标准的方式来连接和操作各种关系型数据库,包括Oracle、MySQL、SQL Server等。 JDBC可以通过调用存储过程执行数据库操作,存储过程是一组预先编译好的SQL语句,可以在需要的时候被调用。在JDBC中,可以通过以下步骤来调用存储过程: 1. 创建CallableStatement对象,该对象用于调用存储过程。 2. 设置存储过程的参数,包括输入参数、输出参数和返回值。 3. 执行存储过程,并获取输出参数和返回值。 下面是一个调用存储过程的示例代码: ``` String sql = "{call my_proc(?, ?, ?)}"; CallableStatement stmt = conn.prepareCall(sql); stmt.setInt(1, 100); stmt.setString(2, "John"); stmt.registerOutParameter(3, Types.INTEGER); stmt.execute(); int result = stmt.getInt(3); ``` 除了调用存储过程JDBC还可以处理数据库事务事务是一组相关的数据库操作,要么全部执行成功,要么全部回滚到之前的状态。在JDBC中,可以通过以下步骤来处理数据库事务: 1. 关闭自动提交模式,这样每个SQL语句就不会自动提交到数据库。 2. 开始事务,即调用Connection对象的beginTransction()方法。 3. 执行一组SQL语句。 4. 如果所有的SQL语句都执行成功,就调用Connection对象的commit()方法提交事务。 5. 如果任何一个SQL语句执行失败,就调用Connection对象的rollback()方法回滚事务。 下面是一个处理数据库事务的示例代码: ``` try { conn.setAutoCommit(false); stmt1.executeUpdate(); stmt2.executeUpdate(); conn.commit(); } catch (SQLException e) { conn.rollback(); } finally { conn.setAutoCommit(true); } ``` 在这个示例中,stmt1和stmt2是两个SQL语句,如果它们都执行成功,就提交事务。如果任何一个SQL语句执行失败,就回滚事务。最后,要记得将自动提交模式重新设置为true。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值