LoginSignup
1
1

More than 5 years have passed since last update.

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

Posted at

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

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

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1