開発中のアプリケーションでは、テーブルからn行を読み取り、ドメイン固有の基準に基づいてそれらの行を選択的に更新する必要があります。この操作中は、データベースの他のすべてのユーザーをロックアウトして、不正な読み取りを回避する必要があります。
トランザクションを開始し、行を読み取り、レコードセットを反復処理しながら一連の更新ステートメントを作成します。レコードセットの読み取りが完了したら、レコードセットを閉じて更新を実行します。この時点でトランザクションをコミットしますが、データベースで更新が実行されていません。
private static SQLiteConnection OpenNewConnection()
{
try
{
SQLiteConnection conn = new SQLiteConnection();
conn.ConnectionString = ConnectionString;//System.Configuration.ConfigurationManager.AppSettings["ConnectionString"];
conn.Open();
return conn;
}
catch (SQLiteException e)
{
LogEvent("Exception raised when opening connection to [" + ConnectionString + "]. Exception Message " + e.Message);
throw e;
}
}
SQLiteConnection conn = OpenNewConnection();
SQLiteCommand command = new SQLiteCommand(conn);
SQLiteTransaction transaction = conn.BeginTransaction();
// Also fails transaction = conn.BeginTransaction();
transaction = conn.BeginTransaction(IsolationLevel.ReadCommitted);
command.CommandType = CommandType.Text;
command.Transaction = transaction;
command.Connection = conn;
try
{
string sql = "select * From X Where Y;";
command.CommandText = sql;
SQLiteDataReader ranges;
ranges = command.ExecuteReader();
sql = string.Empty;
ArrayList ret = new ArrayList();
while (MemberVariable > 0 && ranges.Read())
{
// Domain stuff
sql += "Update X Set Z = 'foo' Where Y;";
}
ranges.Close();
command.CommandText = sql;
command.ExecuteNonQuery();
// UPDATES NOT BEING APPLIED
transaction.Commit();
return ret;
}
catch (Exception ex)
{
transaction.Rollback();
throw;
}
finally
{
transaction.Dispose();
command.Dispose();
conn.Close();
}
return null;
トランザクションを削除すると、すべてが期待どおりに機能します。「ドメインのもの」はドメイン固有であり、レコードセットから値を読み取る以外はデータベースにアクセスしません。ステップを忘れましたか?