我必须向我的数据库添加很多信息。添加此信息大约需要 5-7 分钟。我需要添加交易。
我试过这个:
try {
db.Connection.Open();
db.Transaction = db.Connection.BeginTransaction();
UpdateTable1();
UpdateBigTable2();
...
db.Transaction.Commit();
} catch {
db.Transaction.Rollback();
}
但是当我的数据库更新时,我无法读取数据库或对数据库执行任何操作。
我试图设置IsolationLevel
,但没有任何帮助。
我试过这个:
using (var ts = new TransactionScope()) {
UpdateTable1();
ts.Complete();
}
但是程序在 2-3 分钟后崩溃。
这个解决方案也没有帮助:
var transactionOptions = new TransactionOptions();
transactionOptions.IsolationLevel = System.Transactions.IsolationLevel.Serializable;
transactionOptions.Timeout = TimeSpan.MaxValue;
using (var ts = new TransactionScope(TransactionScopeOption.Required, transactionOptions))
{
...
}
如果我设置了数据库,则在更新时,我可以访问TransactionScopeOption.Suppress
但在这种情况下,事务不起作用。
是的,如果您启动的事务需要大量记录,并且需要很长时间才能完成,那么作为直接结果,竞争操作将被阻止。对于"可序列化"事务尤其如此,因为它们占用的锁最多(包括键范围锁等)。这是交易的本质;它是酸中的我。
选项:
- 不要在一笔巨额交易中做所有事情
- 让您的读取操作故意读取过锁(这是巨大的双刃剑 - 可能没问题,但可能会导致大问题 - 谨慎对待) - 例如
NOLOCK
或READ UNCOMMITTED
。 - 在完整的 SQL 服务器(不是 CE)上,尝试使用快照隔离
using (var trans = new TransactionScope(
TransactionScopeOption.Required,
new TransactionOptions
{
IsolationLevel = IsolationLevel.ReadUncommitted
}
))
{
// Your LINQ to SQL query goes here where you read some data from DB
}
在更新表(插入、删除或更新)时,它们会被锁定,因此,如果要读取尚未提交的数据,则可以使用 Transaction IsolationLevel.ReadUncommit 来允许脏读取
你试过这个吗?
transactionOptions.Timeout = TransactionManager.MaximumTimeout;