mirror of
https://github.com/ncruces/go-sqlite3.git
synced 2026-01-11 21:49:13 +00:00
Discussion #250.
This commit is contained in:
10
conn.go
10
conn.go
@@ -343,6 +343,9 @@ func (c *Conn) GetInterrupt() context.Context {
|
|||||||
//
|
//
|
||||||
// https://sqlite.org/c3ref/interrupt.html
|
// https://sqlite.org/c3ref/interrupt.html
|
||||||
func (c *Conn) SetInterrupt(ctx context.Context) (old context.Context) {
|
func (c *Conn) SetInterrupt(ctx context.Context) (old context.Context) {
|
||||||
|
if ctx == nil {
|
||||||
|
panic("nil Context")
|
||||||
|
}
|
||||||
old = c.interrupt
|
old = c.interrupt
|
||||||
c.interrupt = ctx
|
c.interrupt = ctx
|
||||||
return old
|
return old
|
||||||
@@ -406,11 +409,8 @@ func (c *Conn) BusyHandler(cb func(ctx context.Context, count int) (retry bool))
|
|||||||
|
|
||||||
func busyCallback(ctx context.Context, mod api.Module, pDB ptr_t, count int32) (retry int32) {
|
func busyCallback(ctx context.Context, mod api.Module, pDB ptr_t, count int32) (retry int32) {
|
||||||
if c, ok := ctx.Value(connKey{}).(*Conn); ok && c.handle == pDB && c.busy != nil {
|
if c, ok := ctx.Value(connKey{}).(*Conn); ok && c.handle == pDB && c.busy != nil {
|
||||||
interrupt := c.interrupt
|
if interrupt := c.interrupt; interrupt.Err() == nil &&
|
||||||
if interrupt == nil {
|
c.busy(interrupt, int(count)) {
|
||||||
interrupt = context.Background()
|
|
||||||
}
|
|
||||||
if interrupt.Err() == nil && c.busy(interrupt, int(count)) {
|
|
||||||
retry = 1
|
retry = 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -358,13 +358,10 @@ func (c *conn) Commit() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *conn) Rollback() error {
|
func (c *conn) Rollback() error {
|
||||||
err := c.Conn.Exec(`ROLLBACK` + c.txReset)
|
// ROLLBACK even if interrupted.
|
||||||
if errors.Is(err, sqlite3.INTERRUPT) {
|
old := c.Conn.SetInterrupt(context.Background())
|
||||||
old := c.Conn.SetInterrupt(context.Background())
|
defer c.Conn.SetInterrupt(old)
|
||||||
defer c.Conn.SetInterrupt(old)
|
return c.Conn.Exec(`ROLLBACK` + c.txReset)
|
||||||
err = c.Conn.Exec(`ROLLBACK` + c.txReset)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *conn) Prepare(query string) (driver.Stmt, error) {
|
func (c *conn) Prepare(query string) (driver.Stmt, error) {
|
||||||
|
|||||||
@@ -146,10 +146,7 @@ func TestConn_SetInterrupt(t *testing.T) {
|
|||||||
}
|
}
|
||||||
defer stmt.Close()
|
defer stmt.Close()
|
||||||
|
|
||||||
go func() {
|
time.AfterFunc(time.Millisecond, cancel)
|
||||||
time.Sleep(time.Millisecond)
|
|
||||||
cancel()
|
|
||||||
}()
|
|
||||||
|
|
||||||
// Interrupting works.
|
// Interrupting works.
|
||||||
err = stmt.Exec()
|
err = stmt.Exec()
|
||||||
|
|||||||
3
txn.go
3
txn.go
@@ -20,6 +20,8 @@ type Txn struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Begin starts a deferred transaction.
|
// Begin starts a deferred transaction.
|
||||||
|
// Panics if a transaction is already in-progress.
|
||||||
|
// For nested transactions, use [Conn.Savepoint].
|
||||||
//
|
//
|
||||||
// https://sqlite.org/lang_transaction.html
|
// https://sqlite.org/lang_transaction.html
|
||||||
func (c *Conn) Begin() Txn {
|
func (c *Conn) Begin() Txn {
|
||||||
@@ -119,6 +121,7 @@ func (tx Txn) Commit() error {
|
|||||||
//
|
//
|
||||||
// https://sqlite.org/lang_transaction.html
|
// https://sqlite.org/lang_transaction.html
|
||||||
func (tx Txn) Rollback() error {
|
func (tx Txn) Rollback() error {
|
||||||
|
// ROLLBACK even if interrupted.
|
||||||
return tx.c.exec(`ROLLBACK`)
|
return tx.c.exec(`ROLLBACK`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user