どうやらうまくいったみたいなので、共有します。
ORMLiteはtransactionを貼る時、beginTransactionでトランザクションを行います。
このため、トランザクションが終了するまでは、他のスレッドから検索などが行えません。
beginTransaction とか beginTransactionNonExclusive とかの違いは、ここが参考になります。
http://yuki312.blogspot.jp/2014/10/android-sqlite3-locktransaction.html
ではどうやってbeginTransactionNonExclusive でトランザクションを行えばいいのか?それを解決します。
前提条件として、OrmLiteSqliteOpenHelper を継承した自作のクラスを作成済みである事が条件です。
ここが解りやすいです。
http://qiita.com/opengl-8080/items/133314cfed9b3b404572
今回はORMDatabaseHelper というクラスを作成しておきました。
まずAndroidDatabaseConnectionを継承した自作のDatabaseConnectionを作成します。
public class HogeAndroidDatabaseConnection extends AndroidDatabaseConnection {
/** AndroidDatabaseConnection からdbを奪うためのフィールド */
private final SQLiteDatabase db;
private static Logger logger = LoggerFactory.getLogger(GringAndroidDatabaseConnection.class);
public HogeAndroidDatabaseConnection(SQLiteDatabase db, boolean readWrite) {
super(db, readWrite);
this.db = db;
}
public HogeAndroidDatabaseConnection(SQLiteDatabase db, boolean readWrite, boolean cancelQueriesEnabled) {
super(db, readWrite, cancelQueriesEnabled);
this.db = db;
}
public Savepoint setSavePoint(String name) throws SQLException {
try {
// db.beginTransaction();
db.beginTransactionNonExclusive();
logger.trace("{}: save-point set with name {}", this, name);
return new OurSavePoint(name);
} catch (android.database.SQLException e) {
throw SqlExceptionUtil.create("problems beginning transaction " + name, e);
}
}
private static class OurSavePoint implements Savepoint {
//中略
}
}
OurSavePoint は、戻り値として必要。AndroidDatabaseConnection のソースをパクって作ってしまおう。
次、このDatabaseConnectionを使用するための、ConnectionSourceを作成する。
これはほとんどAndroidConnectionSource のままでいい。どうしてAndroidConnectionSource を継承しているかは後述。
getReadWriteConnection で、HogeAndroidDatabaseConnection を生成する。
ちなみにconnectionフィールドは、privateなので外部から修正できないです。せめてprotectedなら、こんな面倒な事しなくて良かったのに…。
public class HogeAndroidConnectionSource extends AndroidConnectionSource {
//中略。ほとんどAndroidConnectionSource のままでいい
public DatabaseConnection getReadWriteConnection() throws SQLException {
DatabaseConnection conn = getSavedConnection();
if (conn != null) {
return conn;
}
if (connection == null) {
SQLiteDatabase db;
if (sqliteDatabase == null) {
try {
db = helper.getWritableDatabase();
} catch (android.database.SQLException e) {
throw SqlExceptionUtil.create("Getting a writable database from helper " + helper + " failed", e);
}
} else {
db = sqliteDatabase;
}
connection = new HogeAndroidDatabaseConnection(db, true, cancelQueriesEnabled);
if (connectionProxyFactory != null) {
connection = connectionProxyFactory.createProxy(connection);
}
logger.trace("created connection {} for db {}, helper {}", connection, db, helper);
} else {
logger.trace("{}: returning read-write connection {}, helper {}", this, connection, helper);
}
return connection;
}
}
最後。
OrmLiteSqliteOpenHelper を継承した、自作のクラスORMDatabaseHelperでconnectionSourceを上書きします。
connectionSource がprotectedなので、アクセスできます。
public class ORMDatabaseHelper extends OrmLiteSqliteOpenHelper {
public ORMDatabaseHelper( Context context )
{
super(context, context.getString(R.string.db_name), null, context.getResources().getInteger(R.integer.db_version));
connectionSource = new HogeAndroidConnectionSource(this);
}
}
以上です。
これで、トランザクションを使用した時に、beginTransactionNonExclusive を使われるようになります。