1

我试图在 EF Core 中使用 postgresql 的 ROW LOCK。我有一个 .net 核心应用程序和 postgresql 数据库。

在 GetUserContainer 函数中,我使用 FromSqlRaw 构建查询,如下所示

var query = db.UserContainers.FromSqlRaw($"SELECT *, xmin FROM tableName {rowlock}")
     .Where(uc => uc.Id == id);

其中 rowLock 是一个函数参数,其值可以是“FOR UPDATE”或“FOR SHARE”。

我使用下面的代码来读取 UserContainers 并更新

await Task.WhenAll(
   Task.Run(async () =>
   {
    using (var ctx = DbFixture.GetCtx()){
    var repo = new PgUserRepository(ctx);
    var usertoupdate = await repo.GetUserContainer(containerId, 
    dealershipId, eTag, true);
    repo.UpdateUserContainer(usertoupdate, usertoupdate.eTag);
  await repo.Commit();
   }}),
  Task.Run(async () =>
  {
  var message = await TypeOneChannel.Reader.WaitToReadAsync();
  using (var ctx = DbFixture.GetCtx()){
   var repo = new PgUserRepository(ctx);
  repo.Invoking(async (userContainer) => 
  await repo.GetUserContainer(containerId, dealershipId, eTag, true))
  .Should()
 .Throw<Exception>("Because the row is exclusively locked by other task");
 }}));

注意:上面代码中用到的函数片段如下

 public UserContainer UpdateUserContainer(UserContainer item)
    {
       return db.UserContainers.Update(item).Entity;
    }

 public async Task Commit()
    {
       await db.SaveChangesAsync();
    }

根据代码和行锁概念,我希望第二个任务中的 getusercontainer 要么失败,要么等到行锁被释放,因为它被第一个任务锁定。

我试图确保从应用程序端更新用户的 ACID 事务。Postgresql 文档 ( ROW LOCK ) 清楚地表明它在 SQL 中是可能的,但是我需要在 C# 中实现它。

我做错了什么/遗漏了重要的细节吗?或者欢迎任何通过新方法实现这一目标的建议。

4

0 回答 0