为什么悲观锁定在 psql 中对我不起作用?代码不像我期望的那样是并发的

我正在尝试获取和更新列并需要此过程是并发的。因此,我通过进行行级锁定SELECT FOR UPDATE,然后进行计算,然后进行更新,所有这些都在具有隔离级别的事务中进行。repeatable read但是,这仍然不是预期的并发。此列只是一个随机列,而不是主键或外键。


之后我将其更改为乐观锁定并且有效但我试图理解为什么这不起作用。我在下面同时运行了这段代码多次,它的行为方式与我单独运行它相同次数时的行为方式不同。


_, err = s.xStore.ManageTransaction(func(ctx context.Context, tx *sqlx.Tx) (interface{}, error) {

                _, err := tx.Exec("set transaction isolation level repeatable read")

                if err != nil {

                    return nil, err

                }

                c, err = s.xStore.GetForUpdate(x) 

                //Some calculations

                _ = s.xStore.Update(c)

                return nil, nil

            })

            return

    }()

}


这是我使用 FOR UPDATE 锁定行的 Get 查询。


func (s *xStore) GetForUpdate(id string) (*model.X, error) {

    query := `

        SELECT * FROM things where id = $1 FOR UPDATE`


    _, err := s.db.Exec(query, id)

    if err != nil {

        return nil, err

    }


    var x model.X

    err := s.db.Get(&x, query, id)

    err = s.db.Get(&x, query, id)

    if err != nil {

        return nil, err

    }

    return &x, nil

}


大话西游666
浏览 57回答 1
1回答

慕森王

您的代码正在不同事务中执行查询,创建新事务(db.BeginTx)或使用提供的方式,例如:rows := tx.Query(你的查询)做一些计算tx.ExecContexttx.Commit(参考 https://go.dev/doc/database/execute-transactions)
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go