コミットされていない変更についてクエリを実行する必要があり、トランザクションを使用しようとしましたが、例外があると機能しないことがわかりました。
問題を再現するための簡単な例を作成しました。「Tabella」というテーブルが1つしかないデータベースがあり、テーブルには2つのフィールドがあります。「ID」は自動生成された整数で、「Valore」は一意性制約のある整数です。次に、このコードを実行しようとします。
using (TransactionScope scope = new TransactionScope())
{
Db1Container db1 = new Db1Container();
try
{
db1.AddToTabella(new Tabella()
{
Valore = 1
});
db1.SaveChanges();
}
catch { }
try
{
db1.AddToTabella(new Tabella()
{
Valore = 1
});
db1.SaveChanges(); //Unique constraint is violated here and an exception is thrown
}
catch { }
try
{
db1.AddToTabella(new Tabella()
{
Valore = 2
});
db1.SaveChanges();
}
catch { }
//scope.Complete(); //NEVER called
} //here everything should be rolled back
データベースを調べると、トランザクションがロールバックする必要があるため、レコードが含まれていないはずです。代わりに、2つのレコードが見つかります!!!! 1つはValore=1で、もう1つはValore=2です。私は何かが足りないのですか?SaveChangesメソッドへの2回目の呼び出しは、それ自体の変更をロールバックしてトランザクションを「削除」し、次にSaveChangesへの3回目の呼び出しは、1回目と3回目の挿入の変更をコミットするようです(この時点では、トランザクションが存在しないようです)。
また、SaveChanges(false)メソッドを使用しようとしましたが(AcceptAllChangesメソッドを呼び出さなくても)、成功しませんでした。同じ動作をします。
エラーを修正して(たとえば、catchステートメントでのユーザー操作によって)再試行するため、SaveChangesによってトランザクションが自動的にロールバックされることは望ましくありません。
誰かがこれを手伝ってくれますか?それは「バグ」のようで、それは私に本当に大きな頭痛の種を与えています...