我必须对未提交的更改进行查询,并且我尝试使用事务,但是我发现如果有例外情况它不起作用。
我做了一个简单的例子来重现这个问题。 我有一个只有一个名为“Tabella”的表的数据库,该表有两个字段:“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
现在,如果我查看数据库,它应该不包含任何记录,因为事务应该回滚,而是我找到两条记录!一个Valore = 1,一个Valore = 2。 我错过了什么?看起来第二次调用SaveChanges方法回滚它自己的更改并“删除”事务,然后第三次调用SaveChanges会提交第一个和第三个插入的更改(此时它就像事务不存在一样)。 / p>
我也尝试使用SaveChanges(false)方法(即使不调用AcceptAllChanges方法),但没有成功:我有相同的行为。
我不希望SaveChanges自动回滚事务,因为我想纠正错误(例如通过catch语句中的用户交互)并重试。
有人可以帮我吗?这似乎是一个“虫子”,它让我非常头疼......
答案 0 :(得分:0)
您确定永远不会调用scope.Complete()
吗?如果您catch{}
所有异常,代码将继续运行并且将到达Complete语句。相反,您应该让异常传播并在更高级别捕获它。
答案 1 :(得分:0)
对于原始问题,这有点晚了,但也许这对某人有帮助。
此代码应与.net / ef 4和sql server 2008 R2配合使用。
using (TransactionScope scope = new TransactionScope())
{
Db1Container db1 = new Db1Container();
try
{
db1.AddToTabella(new Tabella()
{
Valore = 1
});
db1.SaveChanges();
db1.AddToTabella(new Tabella()
{
Valore = 1
});
db1.SaveChanges(); //Unique constraint is violated here and an exception is thrown
//if we get here then there were no errors thrown on previous SaveChanges()
//calls and we can complete the transaction with no rollback
scope.Complete();
}
catch (Exception)
{
//do nothing
}
}