Spring threadpooltaskexecutor: управление транзакциями

Я пытаюсь сделать вызов асинхронного метода в моем коде сервисного уровня. Некоторый псевдокод для того же, как показано ниже:

public void createXXX ()
{
  dao.saveOrUpdate(entity); // save an entity
  ...................
  ...................
  callAServiceXXX () 
}
...........
...........
public void callAServiceXXX()
{
   SomeEntity entity = dao.getEntity();  // entity NOT NULL
   this.threadPoolTaskExecutor.execute(new Runnable() {
                public void run() {

                try {
                callAMethodXXX()
                }catch()
                {} 

}

public void callAMethodXXX()
{
   SomeEntity entity = dao.getEntity(); // entity always NULL
}

В моем конфигурационном файле spring для bean-компонента сервисного уровня определено следующее, содержащее указанную выше логику:

 <property name="transactionAttributes">
               <props>
                    <prop key="callAServiceXXX">PROPAGATION_REQUIRED</prop>
                    <prop key="callAMethodXXX">PROPAGATION_MANDATORY</prop>
              </props>
          </property>

Как указано выше, когда я пытаюсь получить объект сущности, который я сохраняю в методе createXXX(), он всегда равен NULL, когда вызов dao выполняется из метода callAMethodXXX().

Я не уверен в причине такого поведения. Попробовал несколько других транзакционных атрибутов в файле конфигурации spring, но не добился успеха.

Обходной путь, который я пытался сделать, был:

1) Создайте вспомогательный класс. Внедрите его в этот класс сервисного уровня. 2) Переместите метод callAMethodXXX() в этот вспомогательный класс. 3) Определите <prop key="callAMethodXXX">PROPAGATION_REQUIRES_NEW</prop>, так как я хочу убедиться, что callAMethodXXX() должен выполняться в новой транзакции.

Однако я не хочу использовать дополнительный вспомогательный класс и хочу убедиться, что логика работает нормально с одним классом сервисного уровня.

Любая информация о вышеизложенном будет полезна.

С уважением,


person Anand03    schedule 21.07.2014    source источник


Ответы (1)


Ваш поток Runnable не знает об управлении транзакциями. Возможно, вы можете попробовать добавить в свой управляемый компонент ссылку на себя и добавить TRANSACTION_REQUIRES_NEW для метода callAMethod:

@Component
public class MyService {
    @Autowired
    public MyService myService;

    public void callAServiceXXX() {
       SomeEntity entity = dao.getEntity();
       this.threadPoolTaskExecutor.execute(new Runnable() {
           public void run() {
               try {
                   myService.callAMethodXXX();
               }catch(Exception e){
               }
           }
       });
    }
}

<property name="transactionAttributes">
    <props>
        <prop key="callAServiceXXX">PROPAGATION_REQUIRED</prop>
        <prop key="callAMethodXXX">PROPAGATION_REQUIRES_NEW</prop>
    </props>
 </property>

Отказ от ответственности: у вас все еще могут быть проблемы с этим подходом, поскольку вы вызываете асинхронный метод, и вы не уверены на 100%, что метод saveOrUpdate в отдельной транзакции завершен или нет.

person Magic Wand    schedule 21.07.2014