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

@Transactional метод, вызывающий другой метод без @Transactional anotation?

Я видел метод в классе Service, который был помечен как @Transactional, но он также вызывал некоторые другие методы в том же классе, которые не были помечены как @Transactional.

Означает ли это, что вызов отдельных методов приводит к тому, что приложение открывает отдельные соединения с БД или приостанавливает родительскую транзакцию и т.д.?

Каково поведение по умолчанию для метода без каких-либо аннотаций, который вызывается другим методом с аннотацией @Transactional?

4b9b3361

Ответ 1

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

Если вы вызываете метод с аннотацией @Transactional от метода с @Transactional внутри одного и того же экземпляра, то транзакционное поведение вызываемых методов не окажет никакого влияния на транзакцию. Но если вы вызываете метод с определением транзакции из другого метода с определением транзакции, и они находятся в разных экземплярах, тогда код в вызываемом методе будет следовать определениям транзакций, указанным в вызываемом методе.

Более подробную информацию вы можете найти в разделе Декларативное управление транзакциями spring документации по транзакциям.

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

Ответ 2

  • Означает ли это, что вызов отдельных методов заставляет приложение открывать отдельные подключения к БД или приостанавливать родительскую транзакцию и т.д.

Это зависит от уровня распространения . Вот все возможные значения .

Например, если уровень распространения NESTED, текущая транзакция будет "приостановлена ​​" и будет создана новая транзакция (обратите внимание: фактическое создание вложенной транзакции будет работать только с конкретными менеджерами транзакций)

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

Уровень распространения по умолчанию (то, что вы называете "поведение" ) является REQUIRED. В случае вызова "внутреннего" метода, который имеет аннотацию @Transactional на нем (или транзакционно декларативно через XML), он будет выполняться в той же транзакции, например. "ничего нового" не создано.

Ответ 3

@Transactional отмечает границу транзакции (начало/конец), но сама транзакция привязана к потоку. Как только транзакция начинается, она распространяется по вызову метода до тех пор, пока исходный метод не вернется, и транзакция совершит/откатится.

Если вызывается другой метод, который имеет аннотацию @Transactional, то распространение зависит от атрибута распространения этой аннотации.

Ответ 4

Возможно, вы угадали ответ на свой вопрос из ответов выше. Внутренний метод повлияет на внешний метод, если внутренний метод не аннотирован @Transactional.

В случае, если внутренний метод также аннотирован @Transactional с REQUIRES_NEW, произойдет следующее.

...
@Autowired
private TestDAO testDAO;

@Autowired
private SomeBean someBean;

@Override
@Transactional(propagation=Propagation.REQUIRED)
public void outerMethod(User user) {
  testDAO.insertUser(user);
  try{
    someBean.innerMethod();
  } catch(RuntimeException e){
    // handle exception
  }
}


@Override
@Transactional(propagation=Propagation.REQUIRES_NEW)
public void innerMethod() {
  throw new RuntimeException("Rollback this transaction!");
}

Внутренний метод аннотируется с помощью REQUIRES_NEW и выдает исключение RuntimeException, поэтому он будет устанавливать откат транзакции, но не будет влиять на внешнюю транзакцию. Внешняя транзакция приостанавливается, когда начинается внутренняя транзакция, а затем возобновляет ПОСЛЕ того, как внутренняя транзакция завершается. Они запускаются независимо друг от друга, поэтому внешняя транзакция МОЖЕТ успешно зафиксироваться.