エラー後にコンテキストの状態をロールバックできるように、データコンテキストでトランザクションを使用できますか? もしそうなら、それはどのように機能しますか?
5 に答える
私はいつもテストでそれらを使用しています:)
try
{
dc.Connection.Open();
dc.Transaction = dc.Connection.BeginTransaction();
dc.SubmitChanges();
}
finally
{
dc.Transaction.Rollback();
}
アップデート
これは、事後に常にロールバックします。これをテストで使用します。
DataContext はデフォルトでアンビエント トランザクションを取得するため、トランザクションがスコープ内にあることを確認するだけです。詳細が主な問題になります。
- 必要なオプション (分離レベルなど)
- 新しいトランザクションが必要ですか、それとも既存のトランザクションを再利用しますか (たとえば、監査/ログ操作では、ビジネス操作全体が失敗した場合でもコミットできるように新しいトランザクションが必要になる場合があり、外部トランザクションがロールバックされます)。
これはいくつかのプロトタイプ コードを簡略化したもので、実際のコードではヘルパーを使用して、ポリシー駆動型オプションでトランザクションを作成します (プロトタイプの目的の 1 つは、これらのオプションの影響を調べることでした)。
using (var trans = new TransactionScope(
TransactionScopeOption.Required,
new TransactionOptions {
IsolationLevel = IsolationLevel.ReadCommitted
},
EnterpriseServicesInteropOption.Automatic)) {
// Perform operations using your DC, including submitting changes
if (allOK) {
trans.Complete();
}
}
Complete() が呼び出されない場合、トランザクションはロールバックされます。包含トランザクション スコープがある場合、データベースの変更をコミットするには、内部トランザクションと外部トランザクションの両方が完了している必要があります。
これは TransactionScope メソッドほど単純ではありませんが、私が理解しているように、これは LINQ-to-SQL でそれを行う "正しい" 方法です。System.Transactions への参照は必要ありません。
dataContext.Connection.Open();
using (dataContext.Transaction = dataContext.Connection.BeginTransaction())
{
dataContext.SubmitChanges();
if (allOK)
{
dataContext.Transaction.Commit();
}
else
{
dataContext.Transaction.RollBack();
}
}
もちろん、RollBack は、使用中にさらにデータ操作を行う場合にのみ必要です。それ以外の場合、変更は自動的に破棄されます。
このようなもの、おそらく:
try
{
using (TransactionScope scope = new TransactionScope())
{
//Do some stuff
//Submit changes, use ConflictMode to specify what to do
context.SubmitChanges(ConflictMode.ContinueOnConflict);
scope.Complete();
}
}
catch (ChangeConflictException cce)
{
//Exception, as the scope was not completed it will rollback
}