double timeout_in_hours = 6.0;
MyDataContext db = new MyDataContext();
using (TransactionScope tran = new TransactionScope( TransactionScopeOption.Required, new TransactionOptions(){ IsolationLevel= System.Transactions.IsolationLevel.ReadCommitted, Timeout=TimeSpan.FromHours( timeout_in_hours )}, EnterpriseServicesInteropOption.Automatic ))
{
int total_records_processed = 0;
foreach (DataRow datarow in data.Rows)
{
//Code runs some commands on the DataContext (db),
//possibly reading/writing records and calling db.SubmitChanges
total_records_processed++;
try
{
db.SubmitChanges();
}
catch (Exception err)
{
MessageBox.Show( err.Message );
}
}
tran.Complete();
return total_records_processed;
}
在上面的代码运行时,它成功完成了6或7百次循环迭代。但是,在10到20分钟之后,上面的catch块会捕获以下错误:
{“与当前连接关联的事务已完成但尚未处理。事务必须在连接可用于执行SQL语句之前处理。”}
永远不会进行tran.Complete调用,为什么说完成与连接相关的事务?
为什么在成功提交数百个更改后,与DataContext关联的连接是否突然进入关闭状态? (这是我有时会遇到的另一个错误)。
在对SQL Server进行概要分析时,只有很多连续的选择和插入在运行时没有其他任何内容。探查器捕获的最后一件事是突然的“审核注销”,我不确定这是问题的原因还是副作用。
答案 0 :(得分:1)
哇,最大超时时间受machine.config:http://forums.asp.net/t/1587009.aspx/1
的限制“好的,我们解决了这个问题。显然.net 4.0框架没有 允许您像我们一样在代码中设置transactioncope超时 在过去完成。我们必须通过添加
来更改machine.config< System.Transactions的> < machineSettings maxTimeout =“02:00:00”/>
< defaultSettings timeout =“02:00:00”/> < /system.transactions>到machine.config文件。使用我们没有的2.0框架 我们的代码覆盖了默认值来创建这些条目 开头。“
您在TransactionScope的构造函数中设置的超时似乎被machine.config文件中的最大超时设置忽略或失败。在接受超时参数的TransactionScope构造函数的文档中没有提到这一点:http://msdn.microsoft.com/en-us/library/9wykw3s2.aspx
这让我想知道,如果这是我正在处理的共享托管环境,我无法访问machine.config文件怎么办?实际上没有办法打破事务,因为它涉及在多个表中创建数据,其中关系和标识列的值是自动递增的。多么糟糕的设计决定。如果这是为了保护具有共享主机的服务器,那么这是毫无意义的,因为这样一个长时间运行的事务只会被隔离到我自己的数据库中。此外,如果程序指定更长的超时,那么它显然希望事务花费更长的时间,因此应该允许它。这种限制只是一个毫无意义的障碍IMO会导致问题。另见:TransactionScope maximumTimeout