Spring beans内的事务
我的应用程序在 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.如果我在包含事务注释的调用堆栈中创建多个 HibernateCallback - 它是否表现为事务方法?我是否必须使用相同的会话,并在内部函数之间传递它?
谢谢...
my application conatians hibernate and spring frameworks, on tamcat server and mysql.
i annotated a function as transactional, and i saw that it not behaves as transacitonal method (e.g i can see the changes in the DB in query browser, before the function finish).
the method is executed from a bean, but in different thread, like this:
executor.submit(new Runnable(){
@Override
public void run() {
someSpringService.doDbStuff();
}
});
inside doDbStuff, i am calling to several method, and each method using the template, like this:
return getHibernateTemplate().execute(new HibernateCallback(){
public Object doInHibernate(Session session) throws HibernateException, SQLException {
return session.createCriteria(MyClass.class).add(Restrictions.eq("id", id))
.uniqueResult();
}
});
sometimes, i also exeuctue within the HiberateCallback native sql query, using the session i get as an argument to doInHiberate.
my questions are -
1. is the transactional annotation ignored because i am using different thread?
2. how can i execute the function that is annotated with transactional annotation as a spring bean (and not as a regular function - maybe it will solve 1 )?
3. if i create several HibernateCallback's within a callstack containing transactional annotation - is it behave as a transactional method? do i have to use the same session, and pass it between the inner functions?
thanks...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
当您不是从线程内运行您的方法时,它的行为是否有所不同?这可能是 MySQL/事务隔离问题...
不是在这种情况下。如果您在一个线程中创建一项事务,然后生成一个新线程,则后者不会“继承”该事务。在您的情况下,事务应该在新线程内开始,并且行为正确。
还可以尝试在
doDbStuff()
: 中运行它以进行确认。
你是什么意思?如果您调用的
someSpringService
是由 Spring 注入的,并且doDbStuff()
是一个用@Transactional
注释的公共方法 - 它应该可以正常工作。然而,有一些问题 - 如果您在一个 bean 内部,从私有非事务调用公共事务方法,则可能无法工作。HibernateCallback
足够聪明,可以重用相同的 JDBC 连接 ->休眠会话 ->交易。When you run your method not from within a thread does it behave differently? This might be MySQL/transaction isolation issue...
Not in this case. If you were creating a transaction in one thread and then spawning a new one, the latter would not "inherit" the transaction. In your case the transaction should start inside a new thread, behaving correctly.
Also try running this inside
doDbStuff()
:to make sure.
What do you mean? If you are calling
someSpringService
was injected by Spring anddoDbStuff()
is a public method annotated with@Transactional
- it should just work. There are a few gotchas, however for instance - if you are inside a bean calling public transactional method from private non-transactional one might not work.HibernateCallback
is clever enough to reuse the same JDBC connection -> Hibernate session -> transaction.确保您
的 applicationContext.xml 中有。
Make sure you have
in your applicationContext.xml.