【问题标题】:Spring @transactional with @async Timeout value is not working带有@async Timeout 值的Spring @transactional 不起作用
【发布时间】:2017-11-20 20:03:17
【问题描述】:

我为长时间运行的存储过程调用创建了一个异步服务。一切正常,但是在事务注释的超时属性中给出的指定值之后事务没有超时。代码的结构如下所示(不是真实的......只是骨架......忽略语义/语法)

//asynchronous service
@override
@async("myCustomTaskExecutor")
@Transactional(rollbackfor=Exception.class,timeout=600)
public void serviceMethod(){
    //repository method is invoked.
    repository.callStoredProcedure();
}

//Repository method in the Repository class
@Transactional(rollbackfor=Exception.class,timeout=600)
public void callStoredProcedure(){
    //Stored procedure is called from the private method using hibernate doWork implementation.
    privateCallmethod();
}

private void privateCallmethod() throws ApplicationException{
    Session session = null;
    try{
        session = entityManager.unwrap(Session.class);
        session.doWork(new Work(){
            @Override
            public void execute(Connection connection) throws SQLException {
                OracleCallableStatement statement =null;
                try{
                    //using hibernate 4.x and ref cursors are used...so went on with this approach..
                    //suggest if there is some better approach.
                    String sqlString =“{begin storProcName(?,?)}”;
                    statement = connection.prepareCall(sqlString);
                    statement.setInt(1,5);
                    statement.setString(2,“userName5”);
                    statement.executeUpdate();
                }
                catch(Exception e){
                    throw RunTimeException(e.getMessage);        
                }
                finally{
                    if(statement != null)
                        statement.close();
                    }
                }
            }
        });
    }
    catch(Exception e){
        throw ApplicationException(e.getMessage);        
    }
    //Not using Final block to close the session.Is it an issue ?
}

存储过程端发生延迟(Thread.sleep(700) 未使用)但事务未超时...

问题:

  1. 我想@Transactional 仅在服务方法上就足够了...对使用@Transactional 注释的正确方法提供一点见解 用于此代码设置。
  2. @Transactional 是否适用于 doWork 接口实现中的 JDBC 调用...这是什么问题?
  3. 有些文章建议在CallableStatement 中使用oracle.jdbc.readTimeoutsetQueryTimeout...这是实现此目的的正确方法吗?
  4. 请指出错误并说明原因

【问题讨论】:

    标签: spring hibernate asynchronous jdbc transactions


    【解决方案1】:

    如果@Transactional注解的方法不是类的入口点,除非启用加载时编织(Spring默认为编译时编织)https://stackoverflow.com/a/17698587/6785908

    你应该从这个类之外调用callStoredProcedure(),那么它将是事务性的。如果你调用serviceMethod(),而后者又调用callStoredProcedure(),那么它将不是事务性的

    【讨论】:

    • servicemethd() 和 callStoredProcedure() 方法在不同的类中..是你提到的吗?
    【解决方案2】:

    我使用 setQueryTimeout() 方法解决了这个问题,因为 @Transactional 超时不适用于休眠 dowork() 方法...我猜这是由于休眠工作在不同线程中执行以及它调用的低级 JDBC 方法存储过程...

    注意:这个特定的应用程序使用 Spring 3.x 版本和带有 JPA 2.0 规范的 hibernate 4.x...有点过时的版本

    【讨论】:

      猜你喜欢
      • 2017-06-05
      • 1970-01-01
      • 2012-04-18
      • 1970-01-01
      • 1970-01-01
      • 2018-12-06
      • 2023-03-10
      • 1970-01-01
      相关资源
      最近更新 更多