REQUIRES_NEW в пределах REQUIRES_NEW в пределах REQUIRES_NEW ... и далее - PullRequest
4 голосов
/ 08 декабря 2011

JBoss 4.x
EJB 3.0

Я видел такой код (очень сокращенно):

@Stateless
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public class EJB1 implements IEJB1
{
   @EJB
   private IEJB1 self;

   @EJB 
   private IEJB2 ejb2;

   @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
   public boolean someMethod1()
   {
     return someMethod2();
   }

   @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
   public boolean someMethod2()
   {
     return self.someMethod3();
   }

   @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
   public boolean someMethod3()
   {
     return ejb2.someMethod1();
   }
}

И, скажем, EJB2 - почти точная копия EJB1(те же три метода), и EJB2.someMethod3() вызывает EJB3.someMethod1(), который затем, наконец, в EJB3.someMethod3() записывает в БД.

Это надуманный пример, но мы видели код, аналогичный приведенному выше, в нашемкодовая.Код на самом деле работает просто отлично.

Однако, это похоже на ужасную практику, и меня беспокоит @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) для каждого метода, который даже не выполняет записи в БД.Создает ли это фактически новую транзакцию каждый раз для каждого вызова метода с результатом:

новая транзакция
-новая транзакция
--новая транзакция
--- новая транзакция
... (еще много)
------- новая транзакция (запись в БД)

А затем разворачивается в этой точке?Будет ли это когда-либо причиной проблемы производительности?Дополнительные мысли?

Ответы [ 2 ]

12 голосов
/ 08 декабря 2011

Создает ли это фактически новую транзакцию каждый раз для каждого вызова метода

Нет, это не так.Новая транзакция будет создана только при вызове метода по ссылке EJB из другого компонента.Вызов method2 из method1 внутри того же компонента не вызовет новую транзакцию.

См. Также здесь и здесь .Последняя является исключительно хорошей статьей, объясняющей управление транзакциями в EJB.

Редактировать:
Спасибо @korifey за указание, что method2 фактически вызывает method3 для ссылки на bean-компонент, что приводит к новой транзакции.

4 голосов
/ 08 декабря 2011

Это действительно создает новую транзакцию JTA в каждом EJB, и это должно серьезно повлиять на производительность методов, доступных только для чтения (которые делают только SELECTS, а не обновления). Используйте @SUPPORTS для методов только для чтения

...