Sqlliteデータベースを使用しているマルチスレッドのJavaプログラムで作業しているときに、この問題が発生しました。ファイルロックを使用するので、同時に1つのスレッドしか作業をしていないことを確認しなければなりませんでした。
私は基本的に同期を使用して終了しました。 ConnectionFactoryがdb接続を返すとき、接続を使用するときにロックするロックオブジェクトも返します。だから、手動で同期ロックを行う、またはあなたのためにそれを行い、それ以下のクラスのサブクラスを作成できます。
/**
* Subclass this class and implement the persistInTransaction method to perform
* an update to the database.
*/
public abstract class DBOperationInTransaction {
protected Logger logger = Logger.getLogger(DBOperationInTransaction.class.getName());
public DBOperationInTransaction(ConnectionFactory connectionFactory) {
DBConnection con = null;
try {
con = connectionFactory.getConnection();
if(con == null) {
logger.log(Level.SEVERE, "Could not get db connection");
throw new RuntimException("Could not get db connection");
}
synchronized (con.activityLock) {
con.connection.setAutoCommit(false);
persistInTransaction(con.connection);
con.connection.commit();
}
} catch (Exception e) {
logger.log(Level.SEVERE, "Failed to persist data:", e);
throw new RuntimeException(e);
} finally {
if(con != null) {
//Close con.connection silently.
}
}
}
/**
* Method for persisting data within a transaction. If any SQLExceptions
* occur they are logged and the transaction is rolled back.
*
* In the scope of the method there is a logger object available that any
* errors/warnings besides sqlException that you want to log.
*
* @param con
* Connection ready for use, do not do any transaction handling
* on this object.
* @throws SQLException
* Any SQL exception that your code might throw. These errors
* are logged. Any exception will rollback the transaction.
*
*/
abstract protected void persistInTransaction(Connection con) throws SQLException;
}
とのDBConnection構造体:答えを
final public class DBConnection {
public final Connection connection;
public final String activityLock;
public DBConnection(Connection connection, String activityLock) {
this.connection = connection;
this.activityLock = activityLock;
}
}
感謝を。ことは、アプリケーションは非常に実行する必要があります、それは16または多分32スレッドで実行される可能性があります。そして、それぞれがトランザクションを開始し、多くの処理を行い、結果を取り込み、コミット・ステップで挿入と更新を行います。すべてがjdbcバッチで実行されます。その後、トランザクションがコミットされます。とにかく私の状況では、シリアライズ可能なレベルは32スレッドのためにあまりにも多くなります。私はこれをJavaアプリケーションのキャッシュで解決できることを願っています。 – nesvarbu