Spring + hibernate, вложенный атрибут транзакции NOT_SUPPORTED

public class BusinessService {  //spring bean

  public dumpAllData(List){

    /* Complicated DB operation here
     * We dont want to be in transaction now (because of performance issues)
     */ 

    for(...){           //iterating through whole list
      **updateItem(item);**
    }

  }

  public updateItem(Entity e){
    //saves entity into DB
    //we want to be in transaction now
  }

}

Конфигурация пружины:

<tx:advice id="txAdvice" transaction-manager="wsTransactionManager">
    <tx:attributes>           
      <tx:method name="dumpAllData" propagation="NOT_SUPPORTED" />
      <tx:method name="updateItem" propagation="REQUIRES_NEW" />
    </tx:attributes>
</tx:advice>

Возможно ли иметь вложенное распространение REQUIRED_NEW, которое будет вызываться из метода с распространением NOT_SUPPORTED?

Дело в том, что мы запускаем обширную операцию БД (~ 100 МБ) в dumpAllData(), поэтому мы не хотим быть в транзакции (иначе это было бы проблемой производительности). Но мы хотим быть в транзакции (откат/фиксация) в методе updateItem (где мы делаем простое обновление сущностей).


person Martin V.    schedule 09.01.2012    source источник


Ответы (2)


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

В любом случае, если вам действительно нужно это сделать, то метод updateItem должен быть в другом bean-компоненте Spring, внедренном в bean-компонент BusinessService.

Действительно, Spring может запустить/зафиксировать транзакцию только тогда, когда метод компонента вызывается через прокси. Если вы вызываете метод компонента из другого метода того же компонента, Spring не может перехватить вызов и выполнить управление транзакциями.

person JB Nizet    schedule 09.01.2012
comment
Массивные обновления базы данных, выполняемые за одну транзакцию, могут создать большую нагрузку на базу данных (огромные журналы повторного выполнения в случае оракула). Тогда лучше выполнять их в режиме автоматической фиксации или разбивать на более мелкие фрагменты. - person mrembisz; 09.01.2012
comment
Автофиксация? со спящим режимом? Плохая идея, ИМХО. См. docs.jboss.org/hibernate/core/ 3.6/reference/en-US/html_single/ - person JB Nizet; 09.01.2012
comment
@Mrembisz: разделить на более мелкие куски - да, это наша идея. Мы хотим совершать небольшие изменения одно за другим. У вас есть полезный пример/ссылка? Спасибо - person Martin V.; 09.01.2012
comment
@JBNizet Я объяснил, почему большие транзакции могут влиять на производительность также на стороне БД, независимо от того, какой ORM / язык используется на стороне приложения. - person mrembisz; 09.01.2012
comment
@ martin85 Я полагаю, вы могли бы адаптировать примеры из ссылки в комментарии JB Nizet и ввести еще один цикл вокруг строк, связанных с транзакциями. Я не очень разбираюсь в спящем режиме, поэтому вы можете задать его как еще один вопрос. - person mrembisz; 09.01.2012

Ваша аннотация транзакции в методе обновления не будет перехвачена инфраструктурой транзакций Spring, если она вызывается из какого-либо метода того же класса. Для получения дополнительной информации о том, как работает транзакция Spring, обратитесь к Транзакция Spring.

person Anuj Dhiman    schedule 08.08.2017