数据存储区事务不锁定

问题描述 投票:0回答:1

我正在尝试使用数据存储作为分布式锁。根据 docs,我预计以下内容会因

datastore: concurrent transaction
失败,但它只会失败 <5% of the time. The database used is in Optimistic concurrency mode.

如何让它锁定该实体并使任何并发读/写操作失败?

此代码取自官方文档,在事务读写之间添加了

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)
go transactions locking google-cloud-datastore
1个回答
0
投票

为了确保我们在同一页面上,您的数据库是处于

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
模式下,is 可以使用在一个事务中获得的写锁来延迟其他事务写入者完成,直到锁被释放:https://cloud.google.com/datastore/docs/concepts/交易#concurrency_modes

© www.soinside.com 2019 - 2024. All rights reserved.