транзакции внутри весенних бобов - PullRequest
1 голос
/ 13 сентября 2011

мое приложение содержит Hibernate и Spring Framework, на сервере tamcat и mysql.

Я аннотировал функцию как транзакционную, и я увидел, что она не работает как трансакитональный метод (например, я вижу изменения в БДв браузере запросов, перед завершением функции).

метод выполняется из компонента, но в другом потоке, например:

    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();
        }
    });

, иногда я также выполняю внутри собственного SQL-запроса HiberateCallback, используя сеанс, который я получаю в качестве аргумента для doInHiberate.

myвопросы - 1. аннотация транзакции игнорируется, потому что я использую другой поток?2. как я могу выполнить функцию, аннотированную с помощью транзакционной аннотации, как пружинный компонент (а не как обычную функцию - возможно, она решит 1)?3. если я создаю несколько HibernateCallback в пределах callstack, содержащего транзакционную аннотацию - это ведет себя как транзакционный метод?я должен использовать тот же сеанс и передать его между внутренними функциями?

спасибо ...

Ответы [ 2 ]

1 голос
/ 13 сентября 2011

я могу видеть изменения в БД в браузере запросов до завершения функции

Когда вы запускаете свой метод не из потока, он ведет себя по-другому?Это может быть проблема изоляции MySQL / транзакции ...

  1. игнорируется ли транзакционная аннотация, потому что я использую другой поток?

Не в этомдело.Если вы создаете транзакцию в одном потоке, а затем создаете новый, последний не «унаследует» транзакцию.В вашем случае транзакция должна начинаться в новом потоке, который ведет себя правильно.

Также попробуйте выполнить это внутри doDbStuff():

TransactionSynchronizationManager.isActualTransactionActive()

, чтобы убедиться.

  1. как я могу выполнить функцию, аннотированную с помощью аннотации транзакции, как пружинный компонент (а не как обычную функцию - возможно, она решит 1)?

Что делатьты имеешь в виду?Если вы звоните, someSpringService было введено Spring и doDbStuff() - это публичный метод, помеченный @Transactional - он должен просто работать.Однако есть несколько ошибок: если вы находитесь внутри компонента, вызывающего открытый транзакционный метод из частного нетранзакционного, он может не работать.

  1. если я создаю несколько HibernateCallback в пределах стека вызовов, содержащего транзакционную аннотацию - он ведет себя как транзакционный метод?мне нужно использовать один и тот же сеанс и передавать его между внутренними функциями?

HibernateCallback достаточно умен, чтобы повторно использовать то же соединение JDBC -> сеанс Hibernate -> транзакция.

0 голосов
/ 13 сентября 2011

Убедитесь, что у вас есть

<tx:annotation-driven/>

в вашем приложенииContext.xml.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...