让我们想象我有两个线程,它们在具有ReadCommitted隔离级别的特定于线程的TransactionScopes中执行一些面向数据库的代码。但是有一些表格应该共享数据(不应该创建重复数据)。TransactionScope细微差别
using (var transactionScope = new TransactionScope(IsolationLevel.ReadCommitted))
{
...//some code
if (!_someRepository.IsValueExists(value))
_someRepository.AddData(value);
...//some code
transactionScope.Complete();
}
的问题是两个线程可以检查是否在差不多同一时间存在的数据,如果没有 - 创建复制数据(约束不会在这里帮助:我有防止意外情况发生)。我想这是一个微不足道的问题,但它通常如何解决?
我看到下面的示意性的解决方案:
using (var transactionScope = new TransactionScope(IsolationLevel.ReadCommitted))
{
...//some code
transactionScope.IsolationLevel = IsolationLevel.ReadUncommitted; //change Isolation Level
lock (_sharedDataLockObject)
{
if (!_someRepository.IsValueExists(value))
_someRepository.AddData(value);
}
transactionScope.IsolationLevel = IsolationLevel.ReadCommitted; //reset IsolationLevel
...//some code
transactionScope.Complete();
}
这种解决方案的第一个问题是,TransactionScope的不支持的IsolationLevel修改。但让我们想象我在这里使用ADO.NET事务。不过,我不确定它是否有效。
`快照`隔离级别是否有助于您的情况?这个级别减少了复制修改行时的锁定。这样,其他事务仍然可以读取旧数据,而无需等待解锁。 – whyleee 2011-02-14 20:25:15
@whyleee:但我的问题是添加记录,但没有修改 – SiberianGuy 2011-02-14 20:37:18
但是,如果你需要一个锁,`ReadCommitted`隔离级锁定来自其他事务的写锁的记录。 – whyleee 2011-02-14 20:44:56