Страницы

Поиск по вопросам

четверг, 10 января 2019 г.

Как в java сделать comit в sql если я хочу закомитить много объектов?

Делаю так:
PreparedStatement ps = conn.prepareStatement( "INSERT INTO mydbcall1.Call0 (date,direction,operator,abonentTel,duration,coast1,coast2,corpPhone)" + " VALUES(?, ?, ?, ?, ?, ?, ?, ?)"); try {
ps.setDate(1, new java.sql.Date(call.date.getTime()) ); ps.setString(2, call.direction); ps.setString(3, call.operator); ps.setString(4, call.abonentTel); ps.setInt(5, call.duration); ps.setDouble(6, call.coast1); ps.setDouble(7, call.coast2); ps.setString(8, call.corpPhone); ps.executeUpdate(); // for INSERT, UPDATE & DELETE
} finally { ps.close(); }
метод для 3000 объектов работает больше 1.5 минут.


Ответ

Не создавайте PreparedStatement каждый раз заново. Преимущество PreparedStatement перед обычным Statement именно в том, что можно его заранее отправить на сервер БД для компиляции и переиспользовать повторно. Отправляйте вставки пакетами (batch). Вероятно, вам придется подобрать оптимальный размер пакета. Используйте явное управление транзакцией. По-умолчанию транзакция завершается на каждый запрос к БД (autoCommit = true).
Вот пример с применением этих трех рекомендаций (используется try-with-resources):
private static final String INSERT_STATEMENT = "INSERT INTO mydbcall1.Call0(date,direction,operator,abonentTel,duration,coast1,coast2,corpPhone) VALUES(?, ?, ?, ?, ?, ?, ?, ?)";
// ....
try ( Connection connection = database.getConnection(); PreparedStatement ps = connection.prepareStatement(INSERT_STATEMENT); ) { int i = 0; connection.setAutoCommit(false) for (Call call : calls) { ps.setDate(1, new java.sql.Date(call.date.getTime()) ); ps.setString(2, call.direction); ps.setString(3, call.operator); ps.setString(4, call.abonentTel); ps.setInt(5, call.duration); ps.setDouble(6, call.coast1); ps.setDouble(7, call.coast2); ps.setString(8, call.corpPhone); // ...
ps.addBatch(); i++;
if (i % 1000 == 0 || i == calls.size()) { ps.executeBatch(); // ограничиваем размер одного пакета тысячей вставок } } connection.commit(); } catch(SQLException e) { connection.rollback(); }

Комментариев нет:

Отправить комментарий