-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Ensure txdb.conn is not closed on tx context cancelation (#10935)
* Ensure txdb.conn is not closed on tx context cancelation txdb.conn implements driver.Validation & driver.SessionResetter to prevent database/sql from closing connection if context of transaction was cancelled * Fix race of c.closed
- Loading branch information
1 parent
eab0984
commit 9cc576f
Showing
2 changed files
with
76 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
package pgtest | ||
|
||
import ( | ||
"context" | ||
"testing" | ||
"time" | ||
|
||
"github.com/google/uuid" | ||
"github.com/smartcontractkit/sqlx" | ||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestTxDBDriver(t *testing.T) { | ||
db := NewSqlxDB(t) | ||
dropTable := func() error { | ||
_, err := db.Exec(`DROP TABLE IF EXISTS txdb_test`) | ||
return err | ||
} | ||
// clean up, if previous tests failed | ||
err := dropTable() | ||
assert.NoError(t, err) | ||
_, err = db.Exec(`CREATE TABLE txdb_test (id TEXT NOT NULL)`) | ||
assert.NoError(t, err) | ||
t.Cleanup(func() { | ||
_ = dropTable() | ||
}) | ||
_, err = db.Exec(`INSERT INTO txdb_test VALUES ($1)`, uuid.New().String()) | ||
assert.NoError(t, err) | ||
ensureValuesPresent := func(t *testing.T, db *sqlx.DB) { | ||
var ids []string | ||
err = db.Select(&ids, `SELECT id from txdb_test`) | ||
assert.NoError(t, err) | ||
assert.Len(t, ids, 1) | ||
} | ||
|
||
ensureValuesPresent(t, db) | ||
t.Run("Cancel of tx's context does not trigger rollback of driver's tx", func(t *testing.T) { | ||
ctx, cancel := context.WithCancel(context.Background()) | ||
_, err := db.BeginTx(ctx, nil) | ||
assert.NoError(t, err) | ||
cancel() | ||
// BeginTx spawns separate goroutine that rollbacks the tx and tries to close underlying connection, unless | ||
// db driver says that connection is still active. | ||
// This approach is not ideal, but there is no better way to wait for independent goroutine to complete | ||
time.Sleep(time.Second * 10) | ||
ensureValuesPresent(t, db) | ||
}) | ||
} |