Implement retry logic for UpdateAttributes
This commit is contained in:
parent
3d3fb3c826
commit
6d3a28a6ce
@ -20,8 +20,7 @@ func (db *DB) AddArticle(a *Article) (int64, error) {
|
|||||||
query := `
|
query := `
|
||||||
INSERT INTO articles
|
INSERT INTO articles
|
||||||
(title, description, content, published, rejected, author_id)
|
(title, description, content, published, rejected, author_id)
|
||||||
VALUES
|
VALUES (?, ?, ?, ?, ?, ?)
|
||||||
(?, ?, ?, ?, ?, ?)
|
|
||||||
`
|
`
|
||||||
|
|
||||||
result, err := db.Exec(query, a.Title, a.Description, a.Content, a.Published,
|
result, err := db.Exec(query, a.Title, a.Description, a.Content, a.Published,
|
||||||
|
@ -5,14 +5,19 @@ import (
|
|||||||
"database/sql"
|
"database/sql"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
"math"
|
||||||
|
"math/rand/v2"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/go-sql-driver/mysql"
|
"github.com/go-sql-driver/mysql"
|
||||||
"golang.org/x/term"
|
"golang.org/x/term"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var TxMaxRetries = 3
|
||||||
|
|
||||||
type DB struct {
|
type DB struct {
|
||||||
*sql.DB
|
*sql.DB
|
||||||
}
|
}
|
||||||
@ -92,29 +97,42 @@ func OpenDB(dbName string) (*DB, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (db *DB) UpdateAttributes(a ...*Attribute) error {
|
func (db *DB) UpdateAttributes(a ...*Attribute) error {
|
||||||
tx, err := db.Begin()
|
for i := 0; i < TxMaxRetries; i++ {
|
||||||
if err != nil {
|
err := func() error {
|
||||||
return fmt.Errorf("error starting transaction: %v", err)
|
tx, err := db.Begin()
|
||||||
}
|
if err != nil {
|
||||||
|
return fmt.Errorf("error starting transaction: %v", err)
|
||||||
for _, attribute := range a {
|
|
||||||
query := fmt.Sprintf(`
|
|
||||||
UPDATE %s
|
|
||||||
SET %s = ?
|
|
||||||
WHERE id = ?
|
|
||||||
`, attribute.Table, attribute.AttName)
|
|
||||||
if _, err := tx.Exec(query, attribute.Value, attribute.ID); err != nil {
|
|
||||||
if rollbackErr := tx.Rollback(); rollbackErr != nil {
|
|
||||||
log.Fatalf("error: transaction error: %v, rollback error: %v", err, rollbackErr)
|
|
||||||
}
|
}
|
||||||
return fmt.Errorf("error updating %v in DB: %v", attribute.AttName, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = tx.Commit(); err != nil {
|
for _, attribute := range a {
|
||||||
return fmt.Errorf("error committing transaction: %v", err)
|
query := fmt.Sprintf(`
|
||||||
|
UPDATE %s
|
||||||
|
SET %s = ?
|
||||||
|
WHERE id = ?
|
||||||
|
`, attribute.Table, attribute.AttName)
|
||||||
|
if _, err := tx.Exec(query, attribute.Value, attribute.ID); err != nil {
|
||||||
|
if rollbackErr := tx.Rollback(); rollbackErr != nil {
|
||||||
|
log.Fatalf("error: transaction error: %v, rollback error: %v", err, rollbackErr)
|
||||||
|
}
|
||||||
|
return fmt.Errorf("error updating %v in DB: %v", attribute.AttName, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = tx.Commit(); err != nil {
|
||||||
|
return fmt.Errorf("error committing transaction: %v", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}()
|
||||||
|
if err == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
log.Println(err)
|
||||||
|
|
||||||
|
waitTime := time.Duration(math.Pow(2, float64(i))) * time.Second
|
||||||
|
jitter := time.Duration(rand.IntN(1000)) * time.Millisecond
|
||||||
|
time.Sleep(waitTime + jitter)
|
||||||
}
|
}
|
||||||
return nil
|
return fmt.Errorf("error: %v unsuccessful retries for DB operation, aborting", TxMaxRetries)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *DB) CountEntries(table string) (int64, error) {
|
func (db *DB) CountEntries(table string) (int64, error) {
|
||||||
|
@ -28,8 +28,7 @@ func (db *DB) AddUser(user *User, pass string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
query := `
|
query := `
|
||||||
INSERT INTO users
|
INSERT INTO users (username, password, first_name, last_name, role)
|
||||||
(username, password, first_name, last_name, role)
|
|
||||||
VALUES (?, ?, ?, ?, ?)
|
VALUES (?, ?, ?, ?, ?)
|
||||||
`
|
`
|
||||||
if _, err = db.Exec(query, user.UserName, string(hashedPass), user.FirstName, user.LastName, user.Role); err != nil {
|
if _, err = db.Exec(query, user.UserName, string(hashedPass), user.FirstName, user.LastName, user.Role); err != nil {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user