Pat*_*ick 28 c# entity-framework transactions transactionscope
我TransactionScope
在C#中长期运行.我告诉范围它应该有很长的时间跨度,但我仍然会超时.什么可能导致这个?
TransactionOptions transactionOptions = new TransactionOptions();
transactionOptions.IsolationLevel = IsolationLevel.ReadCommitted;
transactionOptions.Timeout = TimeSpan.MaxValue;
using (var ts = new TransactionScope(TransactionScopeOption.Required, transactionOptions))
{
DoLongCode();
}
Run Code Online (Sandbox Code Playgroud)
Eri*_*der 33
进一步澄清:
事务范围使用计算机配置设置作为最大超时.默认机器超时为10分钟.
将机器配置设置为2小时:
<system.transactions>
<machineSettings maxTimeout="02:00:00"/>
</system.transactions>
Run Code Online (Sandbox Code Playgroud)
可以将app.config或web.config缩减为超时但不能用于超出计算机配置超时.
将app config设置为1小时:
<system.transactions>
<defaultSettings timeout="01:00:00" />
</system.transactions>
Run Code Online (Sandbox Code Playgroud)
此外,我们在达到限制时没有收到任何异常,也没有跟踪或事件日志记录.
此外,TransactionScope对象具有构造函数重载,允许您指定超时,但我不确定如何处理.
Jup*_*aol 25
要允许事务超过10分钟,而无需更改machine.config,请使用此代码
private void SetTransactionManagerField(string fieldName, object value)
{
typeof(TransactionManager).GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Static).SetValue(null, value);
}
public TransactionScope CreateTransactionScope(TimeSpan timeout)
{
SetTransactionManagerField("_cachedMaxTimeout", true);
SetTransactionManagerField("_maximumTimeout", timeout);
return new TransactionScope(TransactionScopeOption.RequiresNew, timeout);
}
Run Code Online (Sandbox Code Playgroud)
用法:
using (var ts = CreateTransactionScope(TimeSpan.FromMinutes(20)))
{
DoLongCode();
ts.Complete();
}
Run Code Online (Sandbox Code Playgroud)
基于这篇文章,文章 的代码最初粘贴在这里.答案中的代码现在已经过重构和简化.
Agh*_*oub 21
如果您在web.config或app.config上没有此部分,则可以在配置文件中验证maxTimeout
验证您的machine.config
<configuration>
<system.transactions>
<machineSettings maxTimeout=""/>
</system.transactions>
</configuration>
Run Code Online (Sandbox Code Playgroud)
调整值
小智 5
它们不起作用,因为您尝试更改超时的上下文错误。
尝试将其更改为更接近有效查询。
您应该具有以下上下文:
using (var txn = new TransactionScope(
TransactionScopeOption.Required,
new TransactionOptions { IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted, Timeout = new TimeSpan(1,0,0) })) // 1 hour or wathever, will not affect anything
{
using (SqlConnection connection = new SqlConnection(ConnectionString))
{
int ct = connection.ConnectionTimeout // (read Only, this is the effective default timeout is 15 seconds)
connection.Open();
SqlCommand select = new SqlCommand(sql.query, connection); // bind to server
select.CommandTimeout = 0; // <-- here does apply infinite timeout
SqlDataReader reader = select.ExecuteReader(); // never stop
Run Code Online (Sandbox Code Playgroud)