Ответ 1
Рассмотрим, что Hibernate должен работать со всеми типами баз данных для всех ситуаций. Их документация заключается в том, как использовать Hibernate из любой поддерживаемой базы данных. И они пытаются поддерживать множество баз данных. Некоторые из этих баз данных могут обрабатывать неудачные транзакции, не требуя явного отката, но Hibernate хочет удостовериться, что он охватывает всех.
Также подумайте о том, что сбой транзакции только для чтения будет крайне редок в реальной жизни. Как только это произойдет, для отката не будет многого, но то, что он делает - освобождение блокировок, как указывает Марк Б, - это не то, что вы хотите пропустить. Так что вы защищаете, это очень крошечная оптимизация (основанная на том, как редко этот путь тренируется), что может иметь плохие последствия в некоторых обстоятельствах. Наличие блокировки не освобождается, это плохое следствие, которое не проявляется до тех пор, пока какая-либо другая транзакция не сработает или не повесится, что очень затрудняет отслеживание причины. Блокировка, которая не будет выпущена, может стать причиной блокировки, поэтому воздействие производительности/доступности может быть ужасным. Также это было бы болью для проверки, если есть проблема, ее можно было бы упустить, пока не возникнет кризис в производственной среде. По многочисленным подсчетам это то, чего вы хотите избежать.
Самая большая проблема здесь заключается в том, что для каждой транзакции необходимо включить код шаблона. Мое предложение состоит в том, чтобы либо реализовать некоторые методы утилиты, используя обратные вызовы, либо шаблон команды (см. Примеры Bauer и King Book Java Persistence with Hibernate для примеров), либо принять структуру. Существует аргумент против фреймворков, что они скрывают детали реализации и усложняют обучение, но у вас уже есть опыт изучения того, как эти части объединены. Существуют зрелые структуры, такие как Seam или Spring который будет обрабатывать это для вас.