假设我有两个线程,它们在具有ReadCommitted隔离级别的线程特定TransactionScopes中执行一些面向数据库的代码。但是有一张表的数据应该是共享的(不应创建重复项)。
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不支持隔离级别修改。但是,让我们想象一下,在这里使用ADO.NET事务。不过我不确定它是否有效。
Snapshot
隔离级别能否帮助您的情况?该级别通过复制修改行来减少锁定。这样,其他事务仍然可以读取旧数据,而无需等待解锁。 - whyleee