Расширение границы транзакции Spring - PullRequest
2 голосов
/ 18 мая 2011

У меня есть цепочка вызовов методов, где A вызывает B, который вызывает C, который вызывает D. A и D имеют аннотацию @Transactional.но B и C нет.какова область границ транзакций в этом случае.B и C являются частью транзакции вообще?

Ответы [ 4 ]

5 голосов
/ 18 мая 2011

По умолчанию A, B, C & D работают в одной транзакции.Уровень распространения транзакции по умолчанию - TX_REQUIRED, что означает, что новая транзакция запускается, если она не существует (A начинает одну, B, C, D участвует).

D может начать новую транзакцию, установив для ее уровня распространения значение TX_REQUIRES_NEW (если ваша среда это поддерживает).В этом сценарии, когда D завершен, приостановленная транзакция возобновляется.Фиксация D не влияет на результат транзакции A. Откат A не откатит D (уже зафиксирован), поскольку они являются отдельными транзакциями.

Кроме того, многие разработчики забывают, что только открытый метод может быть помечен как @TransactionalSpring использует прокси-серверы для управления транзакциями (частные / защищенные методы вызываются для «this» - таким образом, у прокси нет шансов совершить свою магию).Это не обязательно верно, если вы используете внедрение байт-кода вместо прокси.

Если вы хотите узнать больше о шаблонах проектирования транзакций, я настоятельно рекомендую следующую книгу (бесплатно! - требуется регистрация): http://www.infoq.com/minibooks/JTDS. Это очень простое чтение.

3 голосов
/ 18 мая 2011

Это зависит от параметра распространение аннотации @Transactional.

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

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

2 голосов
/ 18 мая 2011

Независимо от того, что произойдет:

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

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

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

1 голос
/ 18 мая 2011

Если вы позвоните B и C из @Transactional A, они все равно будут в транзакции.

Посмотрите на распространение транзакции в весенних документах.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...