golang中的sql事务中的批量upsert

tbi*_*hel 18 sql transactions bulkinsert upsert go

我一直在搞乱golang的sql包与事务,我试图了解如何进行批量upserts而没有每行的"每次插入"往返通信.这里的示例并未真正显示如何进行批量查询.

updateMoney, err := db.Prepare("INSERT INTO balance set money=?, id=? ON DUPLICATE UPDATE balance SET money=money+? WHERE id=?")
...
tx, err := db.Begin()
...
res, err := tx.Stmt(updateMoney).Exec(123.45, 1, 123.45, 1)
res, err := tx.Stmt(updateMoney).Exec(67.89, 2, 67.89, 2)
res, err := tx.Stmt(updateMoney).Exec(10.23, 3, 10.23, 3)
...
tx.Commit()
Run Code Online (Sandbox Code Playgroud)

理想情况下,我可以进行准备好的查询,并建立一个同时发送的upserts列表......但是在这里,我们在每次执行后从数据库中得到一个结果.关于如何解决这个问题的任何建议?

编辑:我的同事找到了这张描述问题的开放票证 ......它看起来比一个交易环境中的严格问题更严重.

One*_*One 8

这取决于您使用的驱动程序,某些驱动程序/数据库根本不支持事务.

例如go-sql-driver/mysql支持交易就好了.

您的代码应该可以使用,或者您可以将其更改为:

tx, err := db.Begin()
...
stmt, err := tx.Prepare(`INSERT INTO balance set money=?, id=? ON DUPLICATE UPDATE balance SET money=money+? WHERE id=?`)
res, err := stmt.Exec(123.45, 1, 123.45, 1)
res, err := stmt.Exec(67.89, 2, 67.89, 2)
res, err := stmt.Exec(10.23, 3, 10.23, 3)
...
tx.Commit()
Run Code Online (Sandbox Code Playgroud)

另请查看此答案,其中包含有关交易的大量详细信息.