Spring beans内的事务

发布于 2024-12-04 02:24:11 字数 989 浏览 1 评论 0原文

我的应用程序在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

骄傲 2024-12-11 02:24:11

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

当您不是从线程内运行您的方法时,它的行为是否有所不同?这可能是 MySQL/事务隔离问题...

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

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

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

TransactionSynchronizationManager.isActualTransactionActive()

以进行确认。

  1. 我如何将使用事务注释注释的函数作为 spring bean 执行(而不是作为常规函数 - 也许它会解决 1 )?

你是什​​么意思?如果您调用的 someSpringService 是由 Spring 注入的,并且 doDbStuff() 是一个用 @Transactional 注释的公共方法 - 它应该可以正常工作。然而,有一些问题 - 如果您在一个 bean 内部,从私有非事务调用公共事务方法,则可能无法工作。

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

HibernateCallback 足够聪明,可以重用相同的 JDBC 连接 ->休眠会话 ->交易。

i can see the changes in the DB in query browser, before the function finish

When you run your method not from within a thread does it behave differently? This might be MySQL/transaction isolation issue...

  1. is the transactional annotation ignored because i am using different thread?

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():

TransactionSynchronizationManager.isActualTransactionActive()

to make sure.

  1. 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 )?

What do you mean? If you are calling someSpringService was injected by Spring and doDbStuff() 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.

  1. 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?

HibernateCallback is clever enough to reuse the same JDBC connection -> Hibernate session -> transaction.

南烟 2024-12-11 02:24:11

确保您

<tx:annotation-driven/>

的 applicationContext.xml 中有。

Make sure you have

<tx:annotation-driven/>

in your applicationContext.xml.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文