transaction
package test.example.com.test25;
import android.content.Context;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteStatement;
import android.util.Log;
public class clsDatabaseTransaction extends clsDatabaseOpen {
clsDatabaseTransaction(Context context)
{
super(context);
//初期化
mNo = 0;
}
private int mNo = 0;
public void setNo(int iNo)
{
mNo = iNo;
}
public int testTest1()
{
Log.d("testTest1","start");
int iResult = 0;
StringBuilder sSQL = new StringBuilder();
if (mNo == 0)
{
sSQL.append(" update tbl1 set fld2 = 10,fld3 = 'a10'");
}
else
{
//setがないSQLエラー
sSQL.append(" update tbl1 fld2 = 10,fld3 = 'a10'");
}
Log.d("sSQL", sSQL.toString());
SQLiteStatement stmt = null;
super.db.beginTransaction();
try
{
Log.d("executeUpdateDelete","start");
stmt = super.db.compileStatement(sSQL.toString());
Log.d("executeUpdateDelete","compileStatement");
iResult = stmt.executeUpdateDelete();
Log.d("iResult",String.valueOf(iResult));
if(iResult < 0)
{
//updateエラー
Log.d("testTest1","1 ROLLBACK TRANSACTION");
return 2;
}
Log.d("executeUpdateDelete","end");
super.db.setTransactionSuccessful();
}
catch (SQLException e)
{
Log.d("error",e.getMessage().toString());
Log.d("testTest1","setTransactionSuccessfulをさせずにendTransactionで確定させる");
return 1;
}
catch (Exception e2)
{
Log.d("error",e2.getMessage().toString());
Log.d("testTest1","setTransactionSuccessfulをさせずにendTransactionで確定させる");
return 1;
}
finally
{
super.db.endTransaction();
Log.d("testTest1","確定処理");
sSQL.delete(0,sSQL.length());
stmt = null;
sSQL = null;
}
Log.d("testTest1","end");
return 0;
}
public int testTest2()
{
Log.d("testTest2","start");
int iResult = 0;
StringBuilder sSQL = new StringBuilder();
Log.d("testTest2 mNo",String.valueOf(mNo));
if(mNo == 0)
{
sSQL.append(" update tbl1 set fld2 = ?,fld3 = ? where fld1 = 11");
}
else
{
//setがないSQLエラー
sSQL.append(" update tbl1 fld2 = ?,fld3 = ? where fld1 = 11");
}
Log.d("sSQL", sSQL.toString());
String[] arrayData =new String[]{"11", "a11"};
Log.d("arrayData.length",String.valueOf(arrayData.length));
super.db.execSQL("BEGIN TRANSACTION");
Log.d("testTest2","BEGIN TRANSACTION");
try
{
Log.d("execSQL","start");
super.db.execSQL(sSQL.toString(), arrayData);
Log.d("execSQL","end");
super.db.execSQL("COMMIT TRANSACTION");
Log.d("testTest2","COMMIT TRANSACTION");
}
catch (SQLException e3)
{
Log.d("error",e3.getMessage().toString());
super.db.execSQL("ROLLBACK TRANSACTION");
return 1;
}
catch (Exception e4)
{
Log.d("error",e4.getMessage().toString());
super.db.execSQL("ROLLBACK TRANSACTION");
return 1;
}
finally
{
sSQL.delete(0,sSQL.length());
sSQL = null;
}
return 0;
}
@Override
public void onCreate(SQLiteDatabase db) {
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
|
「SQLiteStatement」ステートメントを使用した更新処理とexecSQLを使用した更新処理について
トランザクションを実装したサンプルです。
トランザクションを開始したのち以降のステップを
try catchで捕捉しています。
「SQLiteStatement」ステートメントを使用するとロールバックに相当するメソッドの候補が表示されないはずです。
これはトランザクションのコミットに相当する「setTransactionSuccessful」を実行しないとコミットしないまま
データベースのテーブルに反映させないことを意味していると考えられます。
実行した結果もその通りでした。
このことからロールバックを実装する代わりに「setTransactionSuccessful」は実行しないという
ルールがあるようです。
一方、execSQLでは引数にトランザクション、ロールバックおよびコミットを宣言します。
(1)BEGIN TRANSACTION
(2)ROLLBACK TRANSACTION
(3)COMMIT TRANSACTION
トランザクションを開始する方法はSQLiteStatementと同じで
トランザクションを開始したのち、try catchで捕捉します。
クラスの呼び出し側です。
import android.database.sqlite.SQLiteDatabase;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//databaseDrop();
//databaseCreate();
databaseTransaction();
//databaseUpdate();
//databaseDelete();
//databaseInsert();
//databaseSelect();
//databaseOpenClose();
//readFile();
}
private void databaseTransaction()
{
int iResult = 0;
clsDatabaseTransaction cls = new clsDatabaseTransaction(this);
if (cls.DatabaseOpen() > 0)
{
cls = null;
Log.d("databaseUpdate", "データ接続エラーが発生しました。");
return;
}
//beginTransactionを使用
Log.d("databaseTransaction","beginTransactionを使用 ---------------");
cls.setNo(1);//MG
if(cls.testTest1() > 0)
{
Log.d("databaseUpdate", "データ更新エラーが発生しました。");
//このまま再度実行させるため次の2ステップをコメントアウト
//cls = null;
//return;
}
cls.setNo(0);//OK
if(cls.testTest1() > 0)
{
cls = null;
Log.d("databaseUpdate", "データ更新エラーが発生しました。");
return;
}
//execSQLを使用
Log.d("databaseTransaction","execSQLを使用 ---------------");
cls.setNo(1);//NG
if(cls.testTest2() > 0)
{
Log.d("databaseUpdate", "データ更新エラーが発生しました。");
//このまま再度実行させるため次の2ステップをコメントアウト
//cls = null;
//return;
}
cls.setNo(0);//OK
if(cls.testTest2() > 0)
{
cls = null;
Log.d("databaseUpdate", "データ更新エラーが発生しました。");
return;
}
if (cls.DatabaseClose() > 0)
{
cls = null;
Log.d("databaseUpdate", "データ切断エラーが発生しました。");
return;
}
}
}
|
|
|