/ / Idiomatyczny sposób wykonywania wielu zapytań w golang w jednej transakcji - idź

Idiomatyczny sposób wykonywania wielu zapytań w golangu w jednej transakcji - idź

Obecnie walczę (mój drugi dzień) o znalezienie najlepszego sposobu na wykonanie wielu zapytań i zastanawiałem się, czy znasz rozwiązanie.

Mam otwarte * sql.DB Connection, o nazwie myDb i użyj go-sql-driver

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")

for _, q := range s {
_, err := myDb.Exec(q)
if err != nil {
return err
}
}

return nil
}

Czy możliwe jest zatwierdzenie wszystkich powyższych zapytań razem przy użyciu tylko jednej transakcji?

Twoje zdrowie

Odpowiedzi:

3 dla odpowiedzi № 1

Użyj transakcji, takiej jak ta (patrz komentarze w kodzie):

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()
}

0 dla odpowiedzi nr 2

Możesz użyć funkcji opakowanej, aby wykonać logikę zatwierdzania / wycofywania, a nawet rozszerzyć obsługę błędów za pomocą dopasowywania ciągów.

// 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
}