Entity framework 读取、递增和写回在多个用户中唯一的计数器(在EF 4中)
我有一个数据库表和一个相应的实体类(带有更改跟踪代理的POCO),其中有一个成员充当计数器:Entity framework 读取、递增和写回在多个用户中唯一的计数器(在EF 4中),entity-framework,concurrency,entity-framework-4,Entity Framework,Concurrency,Entity Framework 4,我有一个数据库表和一个相应的实体类(带有更改跟踪代理的POCO),其中有一个成员充当计数器: class MyEntity { public virtual int ID { get; set; } public virtual int Counter { get; set; } } 我的web应用程序中有一个函数,它必须通过ID获取该实体,读取计数器(然后用于分配给其他对象),增加它的值,然后将该实体写回数据库,如下所示: public int GetNewCounter(i
class MyEntity
{
public virtual int ID { get; set; }
public virtual int Counter { get; set; }
}
我的web应用程序中有一个函数,它必须通过ID获取该实体,读取计数器(然后用于分配给其他对象),增加它的值,然后将该实体写回数据库,如下所示:
public int GetNewCounter(int ID)
{
int newCounter = 0;
using (MyObjectContext ctx = new MyObjectContext())
{
MyEntity ent = ctx.MyEntities.Where(e => e.ID == ID).Single();
++ent.Counter;
newCounter = ent.Counter;
ctx.SaveChanges();
}
return newCounter;
}
// newCounter is now used for other stuff
两个或两个以上的用户可以同时执行此操作(使用相同ID的实体),我必须确保他们不读取并使用相同的计数器(因此,在第一个用户将递增的计数器存储回数据库之前,第二个用户不应能够获取计数器)
是否可以在读取实体之前“锁定”该实体,并在写回计数器更改后释放锁,然后在其他用户尝试读取同一实体时检查锁?这是一个合理的模式吗
使用实体框架(EF 4)实现此要求需要哪些选项
我对SQL Server和Entity Framework中的并发特性和思想非常不熟悉,如果能在这个特定问题上获得正确方向的帮助,我将不胜感激
提前谢谢你 我非常确定TransactionScope(使用事务)会锁定表,但您可能需要确保这就是您想要的(表锁)。您还可以查看ConcurrencyMode=“fixed”,尽管我不确定这是否能完全满足您的需求。我尝试了一种解决方案,使用乐观并发并遵循该解决方案,将edmx模型文件中MyEntity
中的计数器属性的并发模式设置为固定
我很高兴看到是否有人可以对此进行审查,因为我不知道这是一个好的解决方案,或者是否有更简单的方法
public int GetNewCounter(int ID)
{
int newCounter = 0;
using (MyObjectContext ctx = new MyObjectContext())
{
MyEntity ent = ctx.MyEntities.Where(e => e.ID == ID).Single();
int iRetries = 0;
bool success = false;
do
{
try
{
++ent.Counter;
newCounter = ent.Counter;
ctx.SaveChanges();
success = true;
}
catch (OptimisticConcurrencyException)
{
ctx.Refresh(RefreshMode.StoreWins, ent);
++iRetries;
if (iRetries == 3) // give up after 3 retries
throw;
}
} while (!success);
}
return newCounter;
}
谢谢回复!明天我将更仔细地看一下这两个特性。在我看来,我不需要“表锁”,而是需要“行级”或单个“对象级”的锁,但我不知道是否存在这样的东西。