Как вы определяете, было ли соединение JDBC получено из источника данных с поддержкой JTA или прямого JDBC? - PullRequest
4 голосов
/ 08 октября 2008

Я использую API поставщика для получения соединения JDBC с базой данных приложения. API работает при запуске на сервере приложений или в автономном режиме. Я хочу запустить серию операторов SQL в одной транзакции. Я в порядке с ними происходящими в контексте транзакции JTA, если она существует. Однако, если это не так, мне нужно использовать методы разграничения транзакций JDBC. (Вызов этих методов для соединения JDBC, которое участвует в транзакции JTA, вызывает исключение SQLException.)

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

Есть ли прямой способ сделать это определение?

Спасибо!

Ответы [ 3 ]

4 голосов
/ 12 октября 2008

Даже если это прямой JDBC, вы можете включить транзакцию JTA. Проверка флага autoCommit НЕ поможет в этом отношении. Вы можете участвовать в транзакции, распределенной или иной, если для autoCommit задано значение false. Если для autoCommit установлено значение true, это означает, что вы не участвуете в распределенной транзакции, но значение false означает, что вы не будете выполнять автоматическую фиксацию ... это может быть в любой транзакции.

Я думаю, вам нужно вызвать UserTransaction.getStatus () и убедиться, что он не равен Status.NoTransaction (). Это скажет вам, если вы находитесь в транзакции JTA.

0 голосов
/ 08 октября 2008

То, что говорит Тило, имеет смысл.

В противном случае, не уверен в прямом пути, НО я дам вам "взломать" путь

написать BAD SQL, который, как вы знаете, даст исключение для БД. Это приведет к трассировке стека. По трассировке стека вы можете узнать, является ли это производным соединением JTA или НЕ?

0 голосов
/ 08 октября 2008

Вы можете попробовать проверить флаг autoCommit соединения, чтобы увидеть, находится ли он в транзакции (независимо от того, откуда он пришел). (Видимо, посмотрите принятый ответ, это не очень хорошо работает. Я не удаляю этот ответ, потому что следующее все еще остается:)

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

Обновление: просто перечитайте свой вопрос и увидите, что вы не предоставляете API, но хотите использовать соединение, управляемое контейнером. Но все же, можете ли вы просто обязать (как часть требований вашего приложения), чтобы JTA вступил в силу? Если нет, вы можете предоставить опцию конфигурации для возврата к транзакциям, управляемым вручную. Для такой критической функции кажется разумным требовать правильной конфигурации (вместо того, чтобы пытаться угадать, что будет уместно).

...