2015-09-07 2 views
6

Я использую jOOQ внутри существующего проекта, который также использует какой-то пользовательский JDBC-код. Внутри jOOQ transaction Мне нужно вызвать какой-то другой код JDBC, и мне нужно пройти через активное соединение, чтобы все попадало в одну транзакцию.Как получить базовое соединение внутри транзакции с помощью jOOQ?

Я не знаю, как получить базовое соединение внутри транзакции jOOQ.

create.transaction(configuration -> { 
    DSLContext ctx = DSL.using(configuration); 

    // standard jOOQ code 
    ctx.insertInto(...); 

    // now I need a Connection 
    Connection c = ctx.activeConnection(); // not real, this is what I need 
    someOtherCode(c, ...); 
}); 

Чтение документации и заглядывать немного на исходном коде мой лучший выбор это:

configuration.connectionProvider().acquire() 

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

ответ

2

API jOOQ не делает никаких предположений о существовании «текущего» соединения. В зависимости от ваших конкретных реализаций ConnectionProvider, TransactionProvider и т. Д. Это может быть или не быть возможно.

Ваше обходное правило в целом прекрасное. Просто убедитесь, что вы будете следовать контракт SPI ConnectionProvider «s:

Connection c = null; 
try { 
    c = configuration.connectionProvider().acquire(); 
    someOtherCode(c, ...); 
} 
finally { 
    configuration.connectionProvider().release(c); 
} 

Выше, хорошо, когда вы используете jOOQ-х DefaultTransactionProvider, например.

Примечания есть запрос ожидающего функция #4552, которая позволит вам запускать код в контексте ConnectionProvider и его призывов к acquire() и release(). Это будет выглядеть так:

DSL.using(configuration) 
    .connection(c -> someOtherCode(c, ...)); 
+0

Спасибо @LukasEder за ваш быстрый ответ. Я использую 'DefaultTransactionProvider'. «ConnectionProvider» - это «DataSourceConnectionProvider» и «DefaultConnectionProvider». Я видел, что метод 'ConnectionProvider.release()' ничего не делает в последнем и закрывает соединение в первом. 'DefaultTransactionProvider' говорит в документах, которые _intended для работы с' DefaultConnectionProvider'_. У меня проблемы? ;-) Кажется, что я могу убить транзакцию слишком рано. – sargue

+1

@sargue: Нет, у вас нет проблем. Локальная «Конфигурация» получена из вашей собственной «Конфигурации». «DefaultTransactionProvider» локально использует «DefaultConnectionProvider» и сохраняет «Connection» для области транзакции. Я подозреваю, что это заслуживает дополнительной документации –

+0

Спасибо @LukasEder. Сделано некоторое редактирование ответа и принято как лучшее текущее решение. Может быть, полезен метод поставщика транзакций? 'configuration.transactionProvider(). currentConnection()', который будет возвращать значение null в 'NoTransactionProvider', или выбросить какое-то исключение из других, более экзотических, поставщиков, которые не могут это поддержать. Я могу создать проблему в GitHub, если вы считаете, что это может быть полезно. – sargue

Смежные вопросы