在 CockroachDB 中,批处理和事务如何交互?

In CockroachDB, how do batches and transactions interact?

什么时候应该使用批处理,什么时候应该使用事务?我可以批量嵌入交易吗?一笔交易中的一批?

A batch 是操作的集合,作为一个单元发送到服务器以提高效率。它相当于从不同的线程发送相同的操作作为单独的请求。批处理中的请求可能会乱序执行,并且可能会出现批处理中某些操作成功而其他操作失败的情况。

在 Go 中,批处理是使用批处理对象 DB.B 创建的,并且必须传递给 DB.Run()。例如:

err := db.Run(db.B.Put("a", "1").Put("b", "2"))

相当于:

_, err1 := db.Put("a", "1")
_, err2 := db.Put("b", "2")

一个事务定义了一个一致的原子操作序列。事务保证系统中所有其他操作的一致性:事务的结果不能被看到,除非并且直到事务被提交。由于事务可能需要重试,因此事务由函数对象(通常是闭包)定义,可以多次调用。

在 Go 中,交易是用 DB.Tx method. The *client.Tx parameter to the closure implements a similar interface to DB 创建的;在事务中,您必须对该对象而不是原始数据库执行所有操作。如果你的函数 returns 出错,交易将中止;否则它会提交。这是上一个示例的事务版本(但请参阅下面的更高效版本):

err := db.Tx(func(tx *client.Tx) error {
    err := tx.Put("a", "1")
    if err != nil {
        return err
    }
    return tx.Put("b", "2")
})

前面的示例在开始"b" 写入之前等待"a" 写入完成,然后在提交事务之前等待"b" 写入完成。可以通过在事务中使用批处理来提高效率。 Tx.B 是一个批处理对象,就像 DB.B 一样。在交易中,您可以 运行 批处理 Tx.Run or Tx.CommitTx.Commit 当且仅当批处理中的所有其他操作都成功时才会提交事务,并且比让事务在关闭时自动提交效率更高 returns。最好始终使事务中的最后一个操作成为由 Tx.Commit:

执行的批处理
err := db.Tx(func(tx *client.Tx) error {
    return tx.Commit(tx.B.Put("a", "1").Put("b", "2"))
})