2013-09-26 4 views
2

У меня есть OSGi сверток, в котором я объявляю обслуживание и впрыснуть в него сделку с планом:отката транзакции в OSGi

<bean id="MyServiceImpl" 
      class="com.test.impl.MyServiceImpl"> 
    <jpa:context property="em" unitname="mypu" /> 
    <tx:transaction method="*" value="Required" /> 
</bean> 
<service id="MyService" ref="MyServiceImpl" interface="com.test.api.MyService" /> 

В данной службе у меня есть два метода каждый из которых записывают данные в базы данных, что-то вроде следующего:

public void createParent() throws MyException { 
    Parent parent = new Parent(); 
    ... // Set parent fields 
    em.persist(parent); 
    createChild(); 
    // Checks that could throw MyException 
} 

public void createChild() throws MyException { 
    Child child = new Child(); 
    ... // Set child fields 
    em.persist(child); 
    // Checks that could throw MyException 
} 

Мои проблемы являются следующие:

  1. Если я бросаю выполнения ех ception в методе createParent между em.persist(parent); и createChild(); транзакция откатывается (как и следовало ожидать), и родительский элемент не сохраняется в БД. Однако, если в то же самое время я бросаю MyException (это проверенное исключение), транзакция совершается, и родитель сохраняется. Я видел в Aries mailing list, что объявленное (отмеченное) исключение в декларативной транзакции проекта не вызывает откат. Есть ли способ настроить это поведение и указать, что я хочу, чтобы мое исключение откат транзакции при броске?
  2. Если я бросаю исключение во время выполнения в метод createChild (после em.persist(child);), то дочерний элемент не сохраняется в базе данных, однако родительский объект сохраняется, как если бы оба метода выполнялись в двух разных транзакциях. Почему это? Не следует создавать соединениеChild в транзакции, запущенной createParent?
  3. Если я вызываю исключение во время выполнения в методе createParent после вызова createChild, я получаю то же поведение, что и в пункте 2 (т. Е. Родительский объект сохраняется, а дочерний объект не сохраняется), что меня еще больше смущает, поскольку, даже если я предполагаю, что createChild запускает новую транзакцию, тогда она не должна откатываться назад, когда исключение создается в createParent.
  4. Если в пунктах 2 и 3 выше два метода находятся в разных службах, тогда все работает так, как ожидалось, т.е. исключение, выполняемое во время выполнения любого из методов, возвращает всю транзакцию.

Может кто-нибудь объяснить описанное выше поведение?

ответ

1

После получения некоторой помощи формы списка рассылки Aries оказывается, что проблема была в конфигурации источника данных, а не в конфигурации чертежа. Хотя я использовал MysqlXADataSource в качестве класса драйвера, служба источника данных была зарегистрирована как javax.sql.DataSource, а не javax.sql.XADataSource, что и помешало моим транзакциям.

+0

Не могли бы вы изменить свой исходный вопрос, чтобы включить этот вывод? Я также испытал странное поведение транзакций, и у меня также есть Datasource, а не XADatasource. – ieugen

+0

Поскольку на самом деле это решение проблемы, я предпочел добавить ее в качестве ответа, чтобы люди поняли этот вопрос в будущем. – Christina

0

1: Пару лет назад я спросил то же самое. Хотя весной вы можете указать, что некоторые транзакции должны вызвать откат, а некоторые нет, в проекте вы не можете этого сделать. Через некоторое время я нашел книгу «Чистый код» и прочитал главу «Обработка ошибок». И я проснулся. Я действительно не пытаюсь записать то же, что и в книге. Я думаю, что после того, как вы прочтете его, вы получите некоторые полезные основные мысли, чтобы составить свое мнение, если это правильное поведение.

2: Там может быть два варианта:

  • Вы бросаете исключение до функции сохраняются. Вы поймаете исключение в родительском. Детальная функция только обернута логикой перехвата, если функция вызывается извне, когда нет возврата, когда вызов от ребенка возвращается к родительскому методу любым способом. Просто подумайте об упаковке класса. По крайней мере, если вы не используете манипуляции с байт-кодами или наследование класса времени выполнения (но только классы Java-прокси), вы не можете написать перенос класса таким образом, чтобы он перехватывал вызовы функций между функциями внутри. Вероятно, Овен с ASM пытается сделать трюк (есть ASM-4), но лично мне не нравятся такие трюки.
  • Вы нашли ошибку

3: Это путает меня тоже :). Вы уверены, что не выбрали исключение после сохранения в родительском устройстве, но перед вызовом ребенка? Вероятно, ASM присутствует, и если это есть, у jta-blueprint есть ошибка ... Отладка была бы необходима, чтобы узнать, что произойдет.

4: Приятно слышать, что он может работать как-то :)

+0

Спасибо, Балаз. Я, вероятно, также попробую опубликовать в списке рассылки Овна для очков 2 и 3, если никто другой не сможет дать мне никакого понимания, поскольку они действительно кажутся странными. Что касается 1, я также обнаружил проблему, которую вы открыли с помощью Овна некоторое время назад (https://issues.apache.org/jira/browse/ARIES-772), что было бы действительно отличным решением, но я понимаю, что оно не реализовано все же. Так что, если я хочу откатиться от проверенных исключений, это мой единственный вариант, когда я ввожу менеджера транзакций в свою реализацию и обработку транзакций самостоятельно? Это, несомненно, звучит как то, что я бы не хотел делать ... – Christina

+0

В книге говорится (с более приятными словами), что проверенные исключения были ошибкой языка Java. Non из других языков поддерживает проверенные исключения. Как только исключение должно быть проверено, первоначальная цель исключений теряется. Проверенные исключения больше похожи на возвращаемые значения (с медленным поведением, так как он генерирует stacktrace в конструкторе), и не должно быть отката, если функция возвращается так, как ожидается. Но это больше похоже на философское решение. Я хотел создать такую ​​же проблему раньше, чем вы это делали (я начал реализовывать ее как патч), чем я передумал. –

+0

Да, я согласен, что это философское решение, поэтому я ожидал, что этот проект сможет каким-то образом справиться с этим. Поэтому я думаю, что ответ не ... – Christina

Смежные вопросы