Ari*_*Ari 5 c# entity-framework transactions atomic visual-studio
我需要对某些实体框架模型的某些字段执行原子操作检查值,如果其值为0则增加它.
我想过交易,就像:
bool controlPassed = false;
using (TransactionScope scope = new TransactionScope())
{
var model = ...ModelEntities.first_or_default(...)
if (model.field == 0){
++model.field;
...saveChanges();
controlPassed = true;
}
scope.Complete();
}
if (controlPassed)
{
...
using (TransactionScope scope = new TransactionScope())
{
--model.field;
...saveChanges();
scope.Complete();
}
}
Run Code Online (Sandbox Code Playgroud)
当然,一切都在尝试捕获等.
我的问题是:它会如何运作?
这真的很难检查.我有多线程应用程序.
是否有可能,两个或多个线程将通过控制(检查field == 0并增加它)?
数据库(数据库,表,行,字段)中是否会阻止whout?
我不能让两个或多个线程controlPassed同时在段中.
Lad*_*nka 10
是否有可能,两个或多个线程将通过控制(检查该字段== 0并增加它)?
您有Serializable交易(默认为TransactionScope).这意味着可以有两个带有字段== 0的线程,但是在发生死锁之后立即发生,因为第一个线程的事务在字段上保持共享锁,第二个线程的事务为同一个字段保存另一个共享锁.这些事务都不能将锁升级为独占以保存更改,因为它们在其他事务中被共享锁阻止.我认为RepeatableRead隔离级别会发生同样的情况.
如果您将隔离级别更改为ReadCommitted(默认情况下SaveChanges不TransactionScope使用MS SQL Server时),答案将再次为yes,但这次没有死锁,因为EF使用正常选择而没有任何表提示 - 这意味着当选择完成时没有保持记录锁定.仅保存更改(修改)锁定记录,直到事务提交或回滚.
要ReadCommitted使用select 锁定事务中的记录,必须使用本机SQL查询和UPDLOCK(在select期间锁定记录以进行更新并保持它直到事务结束)表提示.EF查询不支持表提示.
编辑:我写了一篇关于悲观并发的长篇文章,它描述了为什么你的解决方案不起作用以及为了使它正常工作必须改变的原因.
| 归档时间: |
|
| 查看次数: |
1255 次 |
| 最近记录: |