-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtransaction.go
70 lines (57 loc) · 1.42 KB
/
transaction.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
package toki
import (
"context"
"database/sql"
"fmt"
)
// Transaction represents a database transaction
type Transaction struct {
tx *sql.Tx
done bool
}
// TransactionOptions represents options for starting a new transaction
type TransactionOptions struct {
Isolation sql.IsolationLevel
ReadOnly bool
}
// Begin starts a new transaction
func Begin(db *sql.DB) (*Transaction, error) {
return BeginTx(context.Background(), db, nil)
}
// BeginTx starts a new transaction with options
func BeginTx(ctx context.Context, db *sql.DB, opts *TransactionOptions) (*Transaction, error) {
var txOpts *sql.TxOptions
if opts != nil {
txOpts = &sql.TxOptions{
Isolation: opts.Isolation,
ReadOnly: opts.ReadOnly,
}
}
tx, err := db.BeginTx(ctx, txOpts)
if err != nil {
return nil, fmt.Errorf("failed to begin transaction: %w", err)
}
return &Transaction{tx: tx}, nil
}
// Commit commits the transaction
func (t *Transaction) Commit() error {
if t.done {
return fmt.Errorf("transaction already committed")
}
if err := t.tx.Commit(); err != nil {
return fmt.Errorf("failed to commit transaction: %w", err)
}
t.done = true
return nil
}
// Rollback rolls back the transaction
func (t *Transaction) Rollback() error {
if t.done {
return fmt.Errorf("transaction already rolled back")
}
if err := t.tx.Rollback(); err != nil {
return fmt.Errorf("failed to rollback transaction: %w", err)
}
t.done = true
return nil
}