具有@async超时值的Spring @transactional不起作用

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了具有@async超时值的Spring @transactional不起作用相关的知识,希望对你有一定的参考价值。

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

//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. 一些文章建议在oracle.jdbc.readTimeout中使用setQueryTimeoutCallableStatement ......这是实现这一目标的正确方法。
  4. 请指出错误并解释原因
答案

如果@Transactional Annotated方法不是该类的入口点,除非您启用加载时编织(Spring默认为编译时编织),否则它不会是事务性的.https://stackoverflow.com/a/17698587/6785908

你应该从这个类之外调用callStoredProcedure(),然后它将是事务性的。如果你调用serviceMethod()反过来调用callStoredProcedure(),那么它将不会是事务性的

另一答案

我使用setQueryTimeout()方法解决问题,因为@Transactional超时不能与hibernate dowork()方法一起工作...我猜它是由于hibernate工作在不同的线程中执行而它的低级JDBC方法调用存储过程...

注意:此特定应用程序使用非常弹簧3.x版本和hibernate 4.x与JPA 2.0规范......很少过时的版本

以上是关于具有@async超时值的Spring @transactional不起作用的主要内容,如果未能解决你的问题,请参考以下文章

仅在最大日期而不是在组的其他条目中显示具有特定值的组

具有自定义会话超时的 Spring Security [关闭]

async_send 数据未发送

Spring中@Async注解的使用

如何从javascript发送具有2个值的表单?

Spring @async 子线程上下文多租户