Подтвердить что ты не робот

Понимание транзакций Spring - Что происходит, когда транзакционный метод вызывает другой транзакционный метод?

Чтобы понять работу транзакций Spring, я хочу знать, что происходит в следующем случае, когда один метод, помеченный как @Transactional, вызывает другой метод, помеченный как @Transactional.

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

@Service("myService")
@Transactional
public MyService{
   public void myServiceMethod(){
      myDAO.getSomeDBObjects();
   }
}

@Repository("myDAO")
@Transactional
public MyDAOWithUsesBeyondMyService{
   public void getSomeDBObjects(){...}
}

Теперь, если я должен был ввести MyService.myServiceMethod(), он явно начал бы транзакцию. Затем, после сверления в myDAO.getSomeDBObjects(), что произойдет? Был ли факт, что транзакция уже существует, не вызывает никакой новой транзакции или я создаю здесь две транзакции?

Документация (цитируется ниже) о распространении, кажется, охватывает это, но я хотел бы подтвердить свое понимание, это было немного для моего девственного мозга, чтобы понять все сразу.

Распространение. Как правило, весь код выполняется в пределах транзакции будет выполняться в этой транзакции. Однако, у вас есть возможность указать поведения в случае, если транзакционный метод выполняется, когда контекст транзакции уже существует. Например, код может продолжать работать в существующей транзакции ( общий случай); или существующих транзакция может быть приостановлена, а новая транзакция создана. Spring предлагает все вариантов распространения транзакций знакомый с EJB CMT. Чтобы прочитать о семантика транзакции распространение в Spring, см. раздел 10.5.7, "Распространение транзакций".

4b9b3361

Ответ 1

Два ответа:

a) не делайте этого. Используйте @Transactional в уровне обслуживания или уровне dao, но не оба (уровень сервиса является обычным выбором, поскольку вам, вероятно, нужна одна транзакция для одного метода службы)

b), если вы это сделаете, то что происходит, зависит от атрибута propagation аннотации @Transactional и описывается в этом разделе: 10.5.7 Распространение транзакций. В основном: PROPAGATION_REQUIRED означает, что для обоих методов будет использоваться одна и та же транзакция, а PROPAGATION_REQUIRES_NEW - новая транзакция.

О ваших комментариях:

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

Это неверно в вашей ситуации (только если оба метода были в одном классе).

Если bean имеет методы a и b, а a вызывает b, тогда b вызывается в действительном методе, а не прокси, потому что он вызывается из прокси-сервера (a bean не знает, что он связан с внешним миром).

proxy      bean  
a() -->    a()
            |
            V  
b() -->    b()

В вашей ситуации, однако, у службы будет введенный dao-объект, который будет сам прокси, так что у вас будет такая ситуация:

           proxy      bean
service    a() -->    a()
                       |
             /---------/
             |                 
             V
dao        b() -->    b()