久しぶりのブログ更新だが。
val aa = Ref(...);
atomic { implicit txn =>
val a = aa();
// ここでなにか処理をする
// この間に他のスレッドが aa() に書き込みをするとする
// このあとに、読み込みまたは書き込みをする
val b = aa(); // 読み込みをする
// または
aa() = ...; // 書き込みをする
// するとこのタイミングで
// scala.concurrent.stm.skel.RollbackError$
// の例外が発生し
// このあとのatomicブロックの残りのコードは
// 実行されない
...; // 実行されず
// scala.concurrent.stm.skel.RollbackError$ は
// atomic の実装がキャッチして、
// atomicブロックを再実行する
}
atomic { implicit txn =>
val a = aa();
// ここでなにか処理をする
// この間に他のスレッドが aa() に書き込みをするとする
try {
aa() = ...; // 書き込みをする
} catch {
case e => ;
// scala.concurrent.stm.skel.RollbackError$
// をキャッチしてしまうと、
}
// このあとのコードは引き続き実行される
...;
// たとえ RollbackError を例外を
// キャッチして飲み込んでも、
// ロールバックはされる
// atomicブロックは再実行される
}
atomic { implicit txn =>
...;
// atomic はネストすることができる
atomic { implicit txn =>
...;
} // 正しく処理されコミットされたとする
...;
// ここでロールバックされる事態となった場合、
// 内側の atomic で実行された内容も含めて
// ロールバックされる
}


