在一个事务中在golang中执行多个查询的惯用方法
我目前正在努力(第二天)找到执行多个查询的最佳方法,不知道您是否知道解决方案 我有一个名为myDb的open*sql.DB连接,并使用go-sql驱动程序 是否可以仅使用一个事务将上述所有查询提交到一起在一个事务中在golang中执行多个查询的惯用方法,go,Go,我目前正在努力(第二天)找到执行多个查询的最佳方法,不知道您是否知道解决方案 我有一个名为myDb的open*sql.DB连接,并使用go-sql驱动程序 是否可以仅使用一个事务将上述所有查询提交到一起 Cheers使用如下事务(请参见代码中的注释): 您可以使用包装函数执行提交/回滚逻辑,甚至可以使用字符串匹配扩展错误处理 // RDBTransaction is a function which abstracts a sql transaction // into a function w
Cheers使用如下事务(请参见代码中的注释):
您可以使用包装函数执行提交/回滚逻辑,甚至可以使用字符串匹配扩展错误处理
// RDBTransaction is a function which abstracts a sql transaction
// into a function with an isolation level (isolvl) parameter.
// the following integers represent the available isolation levels (isolvl)
// 1: SERIALIZABLE
// 2: REPEATABLE READ
// 3: READ COMMITTED
// 4: READ UNCOMMITTED
func RDBTransaction(db *sql.DB, isolvl int, fn func(*sql.Tx) error) (err error) {
var tx *sql.Tx
tx, err = db.Begin()
if err != nil {
return err
}
// transaction isolation level setting
switch isolvl {
case 1:
_, err = tx.Exec(`set transaction isolation level serializable`)
case 2:
_, err = tx.Exec(`set transaction isolation level repeatable read`)
case 3:
_, err = tx.Exec(`set transaction isolation level read committed`)
case 4:
_, err = tx.Exec(`set transaction isolation level read uncommitted`)
default:
_, err = tx.Exec(`set transaction isolation level serializable`)
}
if err != nil {
return err
}
// catch all, commit/rollback
defer func() {
if err != nil {
tx.Rollback()
return
}
err = tx.Commit()
}()
// run transaction
err = fn(tx)
return err
}
注意:它只适用于truncate语句是事务性的数据库引擎。对于很多人(Oracle、MySQL),情况并非如此。Truncate table通常作为DDL操作实现,而不是DML。非常有帮助!感谢您将延迟声明包括在内!!需要明确的是,一些MySQL引擎(
InnoDB
)确实支持事务,而其他(MyISAM
)则不支持事务。
func TruncateGalleryImport() error {
s := make([]string, 0)
s = append(s, "TRUNCATE TABLE add_map")
s = append(s, "TRUNCATE TABLE album")
s = append(s, "TRUNCATE TABLE album_permission")
s = append(s, "TRUNCATE TABLE album_view")
s = append(s, "TRUNCATE TABLE album_watch")
s = append(s, "TRUNCATE TABLE media")
s = append(s, "TRUNCATE TABLE media_user_view")
s = append(s, "TRUNCATE TABLE media_view")
s = append(s, "TRUNCATE TABLE media_watch")
s = append(s, "TRUNCATE TABLE private_map")
s = append(s, "TRUNCATE TABLE attachment")
s = append(s, "TRUNCATE TABLE attachment_data")
// Get new Transaction. See http://golang.org/pkg/database/sql/#DB.Begin
txn, err := myDb.Begin()
if err != nil {
return err
}
defer func() {
// Rollback the transaction after the function returns.
// If the transaction was already commited, this will do nothing.
_ = txn.Rollback()
}()
for _, q := range s {
// Execute the query in the transaction.
_, err := txn.Exec(q)
if err != nil {
return err
}
}
// Commit the transaction.
return txn.Commit()
}
// RDBTransaction is a function which abstracts a sql transaction
// into a function with an isolation level (isolvl) parameter.
// the following integers represent the available isolation levels (isolvl)
// 1: SERIALIZABLE
// 2: REPEATABLE READ
// 3: READ COMMITTED
// 4: READ UNCOMMITTED
func RDBTransaction(db *sql.DB, isolvl int, fn func(*sql.Tx) error) (err error) {
var tx *sql.Tx
tx, err = db.Begin()
if err != nil {
return err
}
// transaction isolation level setting
switch isolvl {
case 1:
_, err = tx.Exec(`set transaction isolation level serializable`)
case 2:
_, err = tx.Exec(`set transaction isolation level repeatable read`)
case 3:
_, err = tx.Exec(`set transaction isolation level read committed`)
case 4:
_, err = tx.Exec(`set transaction isolation level read uncommitted`)
default:
_, err = tx.Exec(`set transaction isolation level serializable`)
}
if err != nil {
return err
}
// catch all, commit/rollback
defer func() {
if err != nil {
tx.Rollback()
return
}
err = tx.Commit()
}()
// run transaction
err = fn(tx)
return err
}