Логическое сравнение синхронизированного ключевого слова Java и аннотации Spring @Transactional - PullRequest
4 голосов
/ 25 июня 2011

На одной из презентаций о транзакциях Spring / Hibernate я высказал мнение, что ключевое слово synchronized для метода и @Transactional логически имеют много общего.Конечно, они совершенно разные звери, но все же они оба применяются в качестве аспектов к методу и оба контролируют доступ к некоторым ресурсам через некоторый общий монитор (например, запись в дБ).

Было несколько человекв толпе, которая сразу же выступила против и заявила, что мое сравнение смертельно неверно.Я не помню конкретных аргументов, но вижу здесь и кое-что.Например, synchronized работает для всего метода с самого начала, и транзакция вступит в силу только при достижении оператора доступа к БД.Плюс synchronized не предлагает никаких шаблонов блокировки чтения / записи.

Таким образом, вопрос в том, является ли мое сравнение совершенно неправильным, и я никогда не должен его использовать, или, при правильной формулировке, имеет ли смысл представлятьэто опытным инженерам, которые хорошо знают, как работает synchronized, но все же пытаются узнать о транзакциях АОП?Какой должна быть эта формулировка?


Небольшое обновление.

Очевидно, мой вопрос звучал как сравнение транзакций БД с введением метода synchronized в Java.Это не тот случай.Моя идея больше о сравнении сходств в семантике @Transactional и synchronized.

Одной из причин, по которой я это поднял, также была иллюстрация поведения распространения.Например, если @Transactional равен PROPAGATION_REQUIRED, он будет иметь много общего с вводом блока synchronized.Для транзакции: если транзакция присутствует, мы просто продолжаем ее использовать, а если нет, мы ее создадим.Для synchronized, если у нас уже есть монитор, мы продолжаем его, а если нет, мы попытаемся получить его.Конечно, для @Transactional мы не собираемся ограничивать границы метода.

Ответы [ 2 ]

4 голосов
/ 25 июня 2011

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

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

Итак, в конечном итоге - не используйте это сравнение, есть гораздо больше различий, чем они имеют общее.

3 голосов
/ 25 июня 2011

Понятия, воплощенные в аннотации @Transactional, намного сложнее, чем те, которые воплощены в ключевом слове synchronized. Я согласен с комментарием Дж. Б. Низета о том, что ваше сравнение нелогично и может смутить вашу аудиторию.

С помощью синхронизации Java вы всегда точно знаете, что блокируется, с какой точки кода и до какой точки. У вас есть встроенная концепция потоков и очереди потоков, конкурирующих за один и тот же ресурс. Кроме того, вы фактически блокируете код, а не блокируете данные. Это может показаться нюансом, но разница может быть существенной.

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

Во-вторых, семантика изоляции транзакций гораздо сложнее, чем просто синхронизация (только чтение, чтение-запись и т. Д.). Часто изоляция отвечает заботе о целостности данных, а не заботе о доступе к ресурсу. Иногда блокируется только одна запись, иногда целая таблица (опять же, это данные, а не код). Более того, транзакции можно откатить - концепция, которая важна для целостности данных и не существует с synchronized.

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