2013-08-11 8 views
0

Вот мой код для чтения SQL из файла, а затем сделать пакетные обновленияJDBC executeBatch зависает при использовании комбинации MySQL и BoneCP

public void update(Connection conn, File f) { 
    Statement st = null; 
    Scanner sc = null; 
    try { 
     conn.setAutoCommit(false); 
     st = conn.createStatement(); 

     //Scann the file line by line and addBatch each line... 

     st.executeBatch(); 
     conn.commit(); 

     /************************/ 
     conn.setAutoCommit(true); 
     /************************/ 

    } catch (Exception e) { 
     e.printStackTrace(); 
    } finally { 
     try { 
      if (st != null) { st.close();} 
      if (conn != null) { conn.close(); } 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 
} 

Database Я пробовал: HSQLDB(in-process mode), HSQLDB(memory mode), MySQL

DB Pooling Я пробовал: No Pooling(DriverManger), DBCP, BoneCP

Мои работы приложения в следующей последовательности:

1. one batchUpdate() to execute many "create table" and "insert" SQL statement 
2. many executeQuery() to execute many "select" SQL statement 
3. one batchUpdate() to execute many "drop table" statement 

Почти все комбинации БД и БД Бассейн отлично работает без conn.setAutoCommit(true);, что я выделенному в коде, за исключением одного: BoneCP + MySQL. Чтобы эта комбинация работала, я должен положить ее в конец update(). В другом случае программа зависает в начале третьего процесса (2-й бит-пакет).

Мое предположение было то, что он зависает, потому что он ждет выхода write lock, и единственная возможная причина для моего 1-го batchUpdate() удерживания блокировки может быть связана с тем, что я установил соединение, чтобы оно не совершалось автоматически, и это привело к тому, что BoneCP не выпускать write lock. Поэтому я добавил setAutCommit(true), и он сработал. Программа больше не висит.

Итак, я просто хочу спросить, было ли мое предположение правильным? или это из-за чего-то другого? Следует ли считать это ошибкой, поскольку никакая другая комбинация не проявляет такого рода странное поведение? Благодарю.

+0

Что произойдет, если вы выполните DDL в отдельной транзакции? –

+0

Вы хотите разделить 'create' и' insert'? – Will

+0

DDL - это 'create' и' drop', попробуйте использовать их в отдельных транзакциях. –

ответ

0

У BoneCP была ошибка (исправлена ​​в 0.8.0-rc3), при которой autocommit не был установлен в true по умолчанию в соответствии со спецификацией.

Вы можете установить config.setDefaultAutoCommit (true), чтобы обойти проблему.