ORMLite После .commit соединение .setAutoCommit НЕ закрыто

Я использую ORMLite в решении, созданном сервером и клиентами.

На стороне сервера я использую PostgreSQL, на стороне клиента я использую SQLite. В коде я использую те же методы ORMLite, не заботясь об управляемой БД (Postgres или SQLite). Я также использовал объединенное соединение.

У меня не открыто соединение, когда мне нужен запрос Sql, ORMLite позаботится об открытии и закрытии соединения.

Иногда я использую следующий код для выполнения длительной операции в фоновом режиме на стороне сервера, например, в DB PostgreSql.

final ConnectionSource OGGETTO_ConnectionSource = ...... ;
final DatabaseConnection OGGETTO_DatabaseConnection =
     OGGETTO_ConnectionSource.getReadOnlyConnection( "tablename" ) ;
OGGETTO_DAO.setAutoCommit(OGGETTO_DatabaseConnection, false); 
// do long operation with Sql Queries ;
OGGETTO_DAO.commit(OGGETTO_DatabaseConnection);
OGGETTO_DAO.setAutoCommit(OGGETTO_DatabaseConnection, true);

Я заметил, что количество открытых подключений увеличилось, поэтому через какое-то время их количество настолько велико, что сервер останавливается (SqlException слишком много клиентов, подключенных к БД). Я обнаружил, что это из-за фрагмента кода выше, кажется, что после этого фрагмента соединение не закрывается и остается открытым. Конечно, я не могу добавить в конце OGGETTO_ConnectionSource.close (), потому что он закрывает объединенный источник соединения. Если я добавлю в конце OGGETTO_DatabaseConnection.close ();, это не сработает, количество открытых соединений продолжит увеличиваться.

Как это решить?


person Fausto70    schedule 15.03.2021    source источник


Ответы (1)


Я обнаружил, что это из-за фрагмента кода выше, кажется, что после этого фрагмента соединение не закрывается и остается открытым.

Давайте RTFM. Вот javadocs для _ 1_ метод. Процитирую:

Return a database connection suitable for read-only operations. After you are done,
you should call releaseConnection(DatabaseConnection).

Вам нужно сделать что-то вроде следующего кода:

DatabaseConnection connection = connectionSource.getReadOnlyConnection("tablename");
try {
   dao.setAutoCommit(connection false);
   try {
      // do long operation with Sql Queries
      ...
      dao.commit(connection);
   } finally {
      dao.setAutoCommit(connection, true);
   }
} finally {
   connectionSource.releaseConnection(connection);
}

Кстати, это примерно то, что _ 4_ метод работает, хотя в нем есть еще больше блоков try / finally, чтобы гарантировать сброс состояния соединения. Вам, вероятно, стоит на него переключиться. Вот документы для транзакций базы данных ORMLite.

person Gray    schedule 15.03.2021
comment
Прежде всего, спасибо; Я реализовал этот метод на основе вашего ответа: stackoverflow.com/questions/66356373/. Вы написали мне: если вы просто хотите вставить и обновить большое количество записей с более высокой производительностью, вы можете отключить автоматическую фиксацию, выполнить операции, а затем выполнить фиксацию .. Я также попробую с помощью диспетчера транзакций, который я уже использовал . - person Fausto70; 16.03.2021
comment
О диспетчере транзакций Я испытал, что он блокирует БД, и именно этого мне нужно избегать; в противном случае во время длительных фоновых операций другие потоки не могут выполнять действия с БД. - person Fausto70; 16.03.2021
comment
Имеет смысл @ Fausto70. Я думал, что для TransactionManager было бы хорошо поддерживать функцию автоматической фиксации вкл / выкл Callable. - person Gray; 16.03.2021
comment
Привет еще раз @Gray, вы имеете в виду, что я могу установить TransactionManager, чтобы включить / выключить автоматическую фиксацию (и в этом случае я не знаю, как это сделать), или вы имеете в виду, что было бы хорошо, если бы эта функция не существующие сегодня? - person Fausto70; 17.03.2021
comment
К сожалению, этой функции не существует, но было бы неплохо добавить ее @ Fausto70. - person Gray; 17.03.2021