Skip to content

Commit e1bb49a

Browse files
committed
Add configuration setting for transaction isolation level
1 parent 2bd822b commit e1bb49a

File tree

2 files changed

+42
-6
lines changed

2 files changed

+42
-6
lines changed

database/mysql/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
| `x-tls-cert` | | The location of the client certificate file. Must be used with `x-tls-key`. |
1818
| `x-tls-key` | | The location of the private key file. Must be used with `x-tls-cert`. |
1919
| `x-tls-insecure-skip-verify` | | Whether or not to use SSL (true\|false) |
20+
| `x-tx-isolation` | `TxIsolation` | Set transaction isolation level (Default: SERIALIZABLE). |
2021

2122
## Use with existing client
2223

database/mysql/mysql.go

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,18 +30,20 @@ func init() {
3030
var DefaultMigrationsTable = "schema_migrations"
3131

3232
var (
33-
ErrDatabaseDirty = fmt.Errorf("database is dirty")
34-
ErrNilConfig = fmt.Errorf("no config")
35-
ErrNoDatabaseName = fmt.Errorf("no database name")
36-
ErrAppendPEM = fmt.Errorf("failed to append PEM")
37-
ErrTLSCertKeyConfig = fmt.Errorf("to use TLS client authentication, both x-tls-cert and x-tls-key must not be empty")
33+
ErrDatabaseDirty = fmt.Errorf("database is dirty")
34+
ErrNilConfig = fmt.Errorf("no config")
35+
ErrNoDatabaseName = fmt.Errorf("no database name")
36+
ErrAppendPEM = fmt.Errorf("failed to append PEM")
37+
ErrTLSCertKeyConfig = fmt.Errorf("to use TLS client authentication, both x-tls-cert and x-tls-key must not be empty")
38+
ErrInvalidIsolationLevel = fmt.Errorf("invalid isolation level given in x-tx-isolation")
3839
)
3940

4041
type Config struct {
4142
MigrationsTable string
4243
DatabaseName string
4344
NoLock bool
4445
StatementTimeout time.Duration
46+
TxIsolation sql.IsolationLevel
4547
}
4648

4749
type Mysql struct {
@@ -251,6 +253,15 @@ func (m *Mysql) Open(url string) (database.Driver, error) {
251253
}
252254
}
253255

256+
txIsolationParam := customParams["x-tx-isolation"]
257+
txIsolation := sql.LevelSerializable
258+
if txIsolationParam != "" {
259+
txIsolation, err = getIsolationLevel(txIsolationParam)
260+
if err != nil {
261+
return nil, err
262+
}
263+
}
264+
254265
db, err := sql.Open("mysql", config.FormatDSN())
255266
if err != nil {
256267
return nil, err
@@ -261,6 +272,7 @@ func (m *Mysql) Open(url string) (database.Driver, error) {
261272
MigrationsTable: customParams["x-migrations-table"],
262273
NoLock: noLock,
263274
StatementTimeout: time.Duration(statementTimeout) * time.Millisecond,
275+
TxIsolation: txIsolation,
264276
})
265277
if err != nil {
266278
return nil, err
@@ -354,7 +366,7 @@ func (m *Mysql) Run(migration io.Reader) error {
354366
}
355367

356368
func (m *Mysql) SetVersion(version int, dirty bool) error {
357-
tx, err := m.conn.BeginTx(context.Background(), &sql.TxOptions{Isolation: sql.LevelSerializable})
369+
tx, err := m.conn.BeginTx(context.Background(), &sql.TxOptions{Isolation: m.config.TxIsolation})
358370
if err != nil {
359371
return &database.Error{OrigErr: err, Err: "transaction start failed"}
360372
}
@@ -506,3 +518,26 @@ func readBool(input string) (value bool, valid bool) {
506518
// Not a valid bool value
507519
return
508520
}
521+
522+
func getIsolationLevel(input string) (sql.IsolationLevel, error) {
523+
switch input {
524+
case "DEFAULT":
525+
return sql.LevelDefault, nil
526+
case "READ-UNCOMMITTED":
527+
return sql.LevelReadUncommitted, nil
528+
case "READ-COMMITTED":
529+
return sql.LevelReadCommitted, nil
530+
case "WRITE-COMMITTED":
531+
return sql.LevelWriteCommitted, nil
532+
case "REPEATABLE-READ":
533+
return sql.LevelRepeatableRead, nil
534+
case "SNAPSHOT":
535+
return sql.LevelSnapshot, nil
536+
case "SERIALIZABLE":
537+
return sql.LevelSerializable, nil
538+
case "LINEARIZABLE":
539+
return sql.LevelLinearizable, nil
540+
default:
541+
return sql.LevelSerializable, ErrInvalidIsolationLevel
542+
}
543+
}

0 commit comments

Comments
 (0)