Jooq, чтобы использовать существующее соединение для fetchOne или выполнить

1

Я попытался управлять подключением самостоятельно в рамках платформы воспроизведения и реализует поставщик соединения jooq как:

public class PlayConnectionProvider implements ConnectionProvider {

  private Connection connection = null;

  @Override
  public Connection acquire() throws DataAccessException {
    if (connection == null) {
      connection = DB.getConnection();
    }
    return connection;
  }

  @Override
  public void release(Connection released) throws DataAccessException {
    if (this.connection != released) {
      throw new IllegalArgumentException("Expected " + this.connection + " but got " + released);
    }
    try {
      if (connection.getAutoCommit() == true) {
        connection.close();
        connection = null;
      }
    } catch (SQLException e) {
      Logger.error("Error closing connection " + connection, e);
    }
  }
}

Однако, когда я вызываю execute(), кажется, что jooq всегда будет вызывать метод gets() и создавать новое соединение вместо существующего. Я обнаружил, что новое соединение получается по умолчаниюExecuteContext в функции execute():

public final Connection connection() {
    ConnectionProvider provider = this.connectionProvider != null?this.connectionProvider:this.configuration.connectionProvider();
    if(this.connection == null && provider != null) {
        this.connection(provider, provider.acquire());
    }

    return this.connection;
}

Есть ли способ настроить соединение для execute()?

  • 0
    Вы уверены, что не сбрасываете соединение, чтобы null себя в release() ? Какую версию JOOQ вы используете? И просто чтобы быть уверенным: как вы создаете свой ConnectionProvider ?
Теги:
jdbc
jooq
playframework-2.0

1 ответ

0

Вы правы, jOOQ всегда вызывает метод acquire() в начале каждого вызова execute(). Но он также вызывает release() в конце его, и вы, похоже, сами перезагружаете свое кэшированное соединение

if (connection.getAutoCommit() == true) {
    connection.close();
    connection = null;
}

... потому что Play DB.getConnection() возвращает соединение с DB.getConnection() автоматическим фиксацией

Замечание о безопасности потоков

Обратите внимание: если вы кешируете соединение таким образом, ConnectionProvider больше не будет потокобезопасным, и, следовательно, все его объекты не будут потокобезопасными (включая Configuration и DSLContext). Одним из способов обеспечения безопасности этого потока было бы сохранение соединения в ThreadLocal внутри вашего ConnectionProvider

  • 1
    Спасибо, Лукас. Наконец, я получаю одно решение, которое использует DSL.using (connection, SQLDialect.MYSQL), когда я хочу самостоятельно управлять транзакцией, или DSL.using (defaultConnectionProvider, SQLDialect.MYSQL), когда я хочу, чтобы jooq's create автоматически получал ( ) или realease () соединений. Пока транзакция мала внутри одной функции, воспроизведение должно быть в порядке с ее фиксацией или откатом.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню