春豆内的交易

时间:2011-09-13 09:19:39

标签: java hibernate spring transactions

我的应用程序在tamcat服务器和mysql上配置了hibernate和spring框架。

我将一个函数注释为事务性的,我发现它不像交易方式那样(例如,我可以在函数完成之前看到查询浏览器中数据库的更改)。

该方法是从bean执行的,但是在不同的线程中,如下所示:

    executor.submit(new Runnable(){

        @Override
        public void run() {

            someSpringService.doDbStuff();
        }
    });

在doDbStuff里面,我调用了几个方法,并且每个方法都使用模板,如下所示:

    return getHibernateTemplate().execute(new HibernateCallback(){
        public Object doInHibernate(Session session) throws HibernateException, SQLException {
            return session.createCriteria(MyClass.class).add(Restrictions.eq("id", id))
                    .uniqueResult();
        }
    });

有时,我也会在HiberateCallback本机sql查询中执行,使用我获取的会话作为doInHiberate的参数。

我的问题是 - 1.是否忽略了事务注释,因为我使用的是不同的线程? 2.我如何执行使用事务注释作为spring bean注释的函数(而不是常规函数 - 也许它会解决1)? 3.如果我在包含事务注释的callstack中创建了几个HibernateCallback - 它是否表现为事务方法?我是否必须使用相同的会话,并在内部函数之间传递它?

感谢...

2 个答案:

答案 0 :(得分:1)

  

我可以在功能完成之前看到查询浏览器中数据库的更改

当你运行你的方法时,不是从一个线程中运行它的行为有什么不同吗?这可能是MySQL /事务隔离问题......

  
      
  1. 是忽略的事务注释,因为我使用的是不同的线程?
  2.   

不是这种情况。如果您在一个线程中创建一个事务然后生成一个新事务,后者将不会“继承”该事务。在您的情况下,事务应该在新线程内部开始,行为正确。

还可以尝试在doDbStuff()内运行:

TransactionSynchronizationManager.isActualTransactionActive()

确保。

  
      
  1. 如何执行使用事务注释作为spring bean注释的函数(而不是常规函数 - 也许它会解决1)?
  2.   
你是什​​么意思?如果您正在调用someSpringService由Spring注入,doDbStuff()是一个使用@Transactional注释的公共方法 - 它应该可以正常工作。但是有一些问题,例如 - 如果你在bean内部调用来自私有非事务性的公共事务方法可能不起作用。

  
      
  1. 如果我在包含事务注释的callstack中创建了几个HibernateCallback - 它是否表现为事务方法?我是否必须使用相同的会话,并在内部函数之间传递它?
  2.   

HibernateCallback非常聪明,可以重用相同的JDBC连接 - > Hibernate会话 - >事务。

答案 1 :(得分:0)

确保你有

<tx:annotation-driven/>

在applicationContext.xml中。