新人成長記録16th
前回は、DB(DataBase)の操作について書きました
今回は、DBにおけるトランザクション処理について書いていきます
トランザクションは開始時にBEGIN TRANSACTIONの宣言をする必要があります
そして、処理を確定したい場合には、COMMITをします
トランザクション開始前の状態に戻す場合には、ROLLBACKをします
//トランザクションの開始
//db.execSQL("BEGIN TRANSACTION")と同じ意味
db.beginTransaction();
try {
if (db.delete(tableName, whereClause, whereArgs) > 0) {
//成功フラグを立てる
db.setTransactionSuccessful();
}
} finally {
//成功フラグが立っていればCOMMIT、なければROLLBACKが実行される
//db.execSQL("COMMIT TRANSACTION")又は、db.execSQL("ROLLBACK TRANSACTION")と同じ意味
db.endTransaction();
db.close();
}
トランザクションはACID特性と呼ばれる、4つの要素を持つべきとされています
1 – 原子性(Atomicity)
2 – 一貫性(consistency)
3 – 独立性(isolation)
4 – 永続性(durability)
原子性
これ以上に処理を分割することができない最小の単位のこと
処理のすべてが成功か、失敗をし無効になるかのどちらかであることが重要です
トランザクション中の処理A、B、CのAが成功し、Bが失敗した時には、Cの処理を行わずにAとBの処理を無効にして、DBの状態を処理Aが実行される前に戻します
プログラマ感覚で言うと、以下のような感じですかね
if(funcA() && funcB() && funcC()){
//成功時の処理
}else{
//失敗時の処理
}
一貫性
トランザクション処理の前後で、整合性のあるデータであること
Aさんの口座からBさんの口座に振込みをした時に、Aさんの口座からは引く処理は成功して、Bさんの口座に足す処理が失敗してというのは、Aさんの口座から引かれたお金がどこかへ消えたことになり、一貫性が保てていません
独立性
トランザクション処理中のデータが他の操作から参照されないこと
例として、A口座からB口座に5万円を振込時の処理は以下のようになります
状態 | A口座 | B口座 |
---|---|---|
送金前 | 100万円 | 150万円 |
送金中 | 95万円 | 150万円 |
送金後 | 95万円 | 155万円 |
この時に、送金前と送金後のデータのいずれかしか参照はできません
送金中のデータが参照可能の場合、整合性を保てなくなる場合がでてきます
永続性
トランザクション完了後のデータは保存され、失われないということ
この性質を保証するために、基本的にトランザクションのログを記録しておき、障害発生時にはそのログを使用して、障害発生前の状態へ復旧作業を行う
終わりに
BEGIN TRANSACTIONを宣言しない場合には、SQL文を実行するごとに暗黙的にCOMMITされていますので、未宣言時の操作には、注意が必要です
ミスをしないためにも、トランザクション処理をして、失敗がないことを確認してから、COMMITを実行して確定をするのが安全と言えます
今までアプリを作成した中では、トランザクションへの意識はなかったと言えます
次回から、作成する時には処理を考え、適切な場所で実装していきたいです
火曜日担当:poppy
admin at 2016年11月29日 10:00:13