Go语言 数据存储区事务未锁定

6psbrbz9  于 12个月前  发布在  Go
关注(0)|答案(1)|浏览(96)

我正在尝试将数据存储区用作分布式锁。根据文档,我预计以下代码在datastore: concurrent transaction上会失败,但它只失败了<5%的时间。使用的数据库处于乐观并发模式。
我怎样才能让它锁定该实体并使任何并发读/写操作失败?
这段代码取自官方文档,在事务读写之间添加了一个Put

ctx := context.Background()
    client, err := datastore.NewClientWithDatabase(ctx, "project-id", "database-id")
    if err != nil {
        panic(err)
    }

    type Counter struct {
        Count int
    }

    var count int
    key := datastore.NameKey("Counter", "singleton", nil)
    if _, err = client.RunInTransaction(ctx, func(tx *datastore.Transaction) error {
        var x Counter
        if err := tx.Get(key, &x); err != nil && err != datastore.ErrNoSuchEntity {
            return err
        }

        y := x
        y.Count = 10
        if _, err = client.Put(ctx, key, &y); err != nil {
            return err
        }

        x.Count++
        if _, err = tx.Put(key, &x); err != nil {
            return err
        }
        count = x.Count
        return nil
    }); err != nil {
        panic(err)
    }

    if err = client.Delete(ctx, key); err != nil {
        panic(err)
    }

    fmt.Println("COUNT:", count)
xdnvmnnf

xdnvmnnf1#

只是为了确保我们在同一页上,你的数据库是在OPTIMISTIC模式,还是OPTIMISTIC_WITH_ENTITY_GROUPS模式?
https://cloud.google.com/datastore/docs/concepts/transactions#view_concurrency_mode
假设它使用OPTIMISTIC并发,启动事务并通过tx.Get(key, &x)执行读取不会阻止另一个写入者修改同一文档。但是,假设client.Put(ctx, key, &y)是一个阻塞操作,在RunInTransaction主体完成执行之前完成,则整个RunInTransaction操作应始终失败。
PESSIMISTIC模式下,可以使用在一个事务中获得的写锁来延迟其他事务写入器的完成,直到锁被释放:https://cloud.google.com/datastore/docs/concepts/transactions#concurrency_modes

相关问题