Help us understand the problem. What is going on with this article?

ORMLiteでbeginTransactionNonExclusiveでトランザクションを作成する

More than 5 years have passed since last update.

どうやらうまくいったみたいなので、共有します。

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を作成します。

HogeAndroidDatabaseConnection.java
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なら、こんな面倒な事しなくて良かったのに…。

HogeAndroidConnectionSource.java
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なので、アクセスできます。

ORMDatabaseHelper.java
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 を使われるようになります。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away