Является ли когда-нибудь хорошей практикой использование нетранзакционных EJB-методов «чтения»? - PullRequest
8 голосов
/ 19 августа 2011

Это очень скромный вопрос.

В некоторых статьях указывается, что всегда следует использовать транзакции базы данных, даже для простых операций чтения. Вот произвольный пример, который имеет для меня большой смысл: http://nhprof.com/Learn/Alerts/DoNotUseImplicitTransactions В самой документации Hibernate также сказано:

Всегда используйте четкие границы транзакции, даже для операций только для чтения.

ОК, кажется достаточно ясным. Это всегда было моим предположением, а именно. что поскольку транзакции в любом случае будут применяться неявно на уровне базы данных во всех случаях, вероятно, лучше всегда объявлять их явно.

Затем я читаю другие статьи, подобные этой: http://www.ibm.com/developerworks/java/library/j-ts1/index.html#never (обратите внимание на выноску). В этой статье говорится, частично:

Никогда не говори никогда

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

Немного о тупиках и плохой пропускной способности также имеет смысл для меня.

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

Теперь я возвращаюсь в область сервера приложений и транзакций XA.

Если у меня есть метод EJB, который выполняет операции только для чтения, то будет ли хорошей практикой всегда объявлять его транзакционным (следуя духу рекомендаций Hibernate выше)? Или пометить его как @TransactionAttribute(TransactionAttributeType.SUPPORTS) не очень много о стратегии транзакций базы данных рядом с металлом?

Я имею в виду, что транзакция EJB (JTA) происходит на уровне сервера приложений. Может случиться так (я не знаю), что когда сервер приложений Java EE взаимодействует с Hibernate, Hibernate всегда будет принудительно выполнять явные транзакции на уровне базы данных, независимо от действующей политики транзакций на уровне приложений. Поэтому статьи, посвященные Hibernate, которые я привел здесь, могут не относиться к транзакции JTA уровня сервера приложений - возможно, - это хорошая практика, чтобы помечать методы только для чтения как @TransactionAttribute(TransactionAttribute.SUPPORTS) вместо REQUIRED.

Что здесь думают люди? Все указатели - даже на элементарную информацию - приветствуются.

Ответы [ 2 ]

3 голосов
/ 23 августа 2011

Я не вижу проблем в использовании TransactionAttribute.SUPPORTS, но вы должны быть уверены в контексте, в котором вы работаете.

То, что вы на самом деле говорите: «Меня не волнует грязное чтение». Или фантом читает. Данные, которые вы возвращаете пользователю, не обязательно находятся в согласованном состоянии, и для многих приложений это просто замечательно.

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

Короче говоря, я думаю, что аннотации EJB3 Tx существуют там для определенной цели. Если вы правильно понимаете их семантику и свое приложение, вы можете принять обоснованное решение о том, какой режим Tx является более подходящим.

S,
ALR

2 голосов
/ 20 августа 2011

Если у меня есть метод EJB, который выполняет операции только для чтения, рекомендуется ли всегда объявлять его транзакционным (следуя духу приведенного выше совета Hibernate)?

На мой взгляд, это зависит от требований варианта использования, который вы реализуете.Если допускаются неповторяющиеся чтения и / или фантомные чтения, ваш метод только для чтения не обязательно должен всегда выполняться внутри транзакции.Для некоторых типов поиска или создания отчетов это приемлемо.С другой стороны, подумайте о ситуации, подобной этой:

List<Post> posts = findAllPosts();
for (Post p : posts) {
  Statistics s = findStatisticByPostId(p.id);
  doSomethingWithStatistics(s);
}

В таком случае возможно, чтобы одно сообщение вернуло свою статистику к времени T1, а другое - к времени T2, where T2 > T1, поскольку каждый вызов findStatisticByPostId будет выполняться внутри собственной транзакции.И обе записи могли видеть некоторую статистику во время (T1...T2).

. Поэтому, если вы генерируете отчет в соответствии с возвращенными объектами Statistics, невозможно гарантировать, что отчетосновываясь на всей статистике, которая была доступна к тому времени T2.

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

...