Version v0.26 of the documentation is no longer actively maintained. The site that you are currently viewing is an archived snapshot. For up-to-date documentation, see the latest version.

Transaction

トランザクション

概要

KomapperはJDBCやR2DBCのConnectionが持つトランザクション機能をラップした高レベルAPIを提供します。

このAPIを使うには専用のモジュールをGradleの依存関係に宣言します。

JDBCを使う場合は次のようにkomapper-tx-jdbcを宣言します。

val komapperVersion: String by project

dependencies { 
    implementation("org.komapper:komapper-tx-jdbc:$komapperVersion")
}

R2DBCを使う場合は次のようにkomapper-tx-r2dbcを宣言します。

val komapperVersion: String by project

dependencies {
    implementation("org.komapper:komapper-tx-r2dbc:$komapperVersion")
}

トランザクションの制御

Komapperが提供するトランザクション制御のためのAPIはJDBC版とR2DBC版で異なりますが見た目上のインターフェースは統一されています。 ここでは明らかに異なる部分を除いてJDBC版とR2DBC版を合わせて説明します。

JdbcDatabaseもしくはR2dbcDatabaseが下記のようにdbという変数で宣言されていることを前提に説明を進めます。

val db = JdbcDatabase.create("jdbc:h2:mem:example;DB_CLOSE_DELAY=-1")
val db = R2dbcDatabase.create("r2dbc:h2:mem:///example;DB_CLOSE_DELAY=-1")

開始と終了

JDBC版とR2DBC版のそれぞれのモジュールに定義されたwithTransaction拡張関数の呼び出すことでトランザクションを開始できます。

db.withTransaction {
    ..
}

withTransaction拡張関数にはトランザクション属性とトランザクション分離レベルを指定できます。

db.withTransaction(
  transactionAttribute = TransactionAttribute.REQUIRES_NEW, 
  isolationLevel = IsolationLevel.SERIALIZABLE) {
    ..
}

トランザクション属性を指定しない場合、トンランザクションがなければ作成しすでに存在すればそのトランザクションに参加します。

トランザクション分離レベルを指定しない場合にどのレベルになるかは利用するドライバの挙動に従います。

withTransaction拡張関数の呼び出しが終わるとトランザクションはコミットもしくはロールバックされます。

ロールバックされる条件は次のとおりです。

  • withTransaction拡張関数の呼び出しが例外のスローにより終了する
  • withTransaction拡張関数に渡されたラムダ式の中で明示的にロールバックを行う

ロールバックの条件に合致しない場合コミットされます。

明示的なロールバック

withTransaction拡張関数に渡されたラムダ式の中でsetRollbackOnly関数を呼び出すとwithTransaction拡張関数終了時にロールバックが実行されます。

db.withTransaction {
    ..
    setRollbackOnly()
    ..
}

すでにsetRollbackOnly関数を呼び出したかどうかはisRollbackOnly関数で確認できます。

db.withTransaction {
    ..
    if (isRollbackOnly()) {
        ..
    }
    ..
}

新規トランザクションの開始と終了

すでに開始されたトランザクションの中で別のトランザクションを新しく開始するにはwithTransaction拡張関数に渡されたラムダ式の中でrequiresNew関数を呼び出します。

db.withTransaction {
    ..
    requiresNew {
        ..
    }
    ..
}

requiresNew関数にはトランザクション分離レベルを指定できます。

db.withTransaction {
    ..
    requiresNew(isolationLevel = IsolationLevel.SERIALIZABLE) {
        ..
    }
    ..
}

トランザクション分離レベルを指定しない場合にどのレベルになるかは利用するドライバの挙動に従います。

requiresNew関数の呼び出しが終わるとトランザクションはコミットもしくはロールバックされます。

ロールバックされる条件は次のとおりです。

  • requiresNew関数の呼び出しが例外のスローにより終了する
  • requiresNew関数に渡されたラムダ式の中で明示的にロールバックを行う

ロールバックの条件に合致しない場合コミットされます。

最終更新 September 20, 2021: Polish (b0b89bb)