]> Cypherpunks repositories - gostls13.git/commit
database/sql: fix transaction leak
authorkirk <kirk91.han@gmail.com>
Mon, 4 Dec 2017 02:53:53 +0000 (10:53 +0800)
committerDaniel Theophanes <kardianos@gmail.com>
Tue, 5 Dec 2017 16:47:21 +0000 (16:47 +0000)
commitbcf964de5e16486cec2e102c929768778f50eea2
tree632787b42d2f64a9068300719be8f579860f327c
parentdd7cbf3a846c2cb125ac65173abaf6a8b9f903ff
database/sql: fix transaction leak

When the user context which passed in (*DB)BeginTx is canceled or
timeout, the current implementation could cause db transaction leak
in some extreme scenario.

Goroutine 1:
        Call (*DB) BeginTx begins a transaction with a userContext.
        In (*DB)BeginTx, a new goroutine (*Tx)awaitDone
        which monitor context and rollback tx if needed will be created

Goroutine 2(awaitDone):
        block on tx.ctx.Done()

Goroutine 1:
        Execute some insert or update sqls on the database

Goroutine 1:
        Commit the transaction, (*Tx)Commit set
        the atomic variable tx.done to 1

Goroutine 3(maybe global timer):
        Cancel userContext which be passed in Tx

Goroutine 1:
        (*Tx)Commit checks tx.ctx.Done().
        Due to the context has been canceled, it will return
        context.Canceled or context.DeadlineExceeded error immediately
        and abort the real COMMIT operation of transaction

Goroutine 2:
        Release with tx.ctx.Done() signal, execute (*Tx)rollback.
        However the atomic variable tx.done is 1 currently,
        it will return ErrTxDone error immediately and
        abort the real ROLLBACK operation of transaction

Fixes #22976

Change-Id: I3bc23adf25db823861d91e33d3cca6189fb1171d
Reviewed-on: https://go-review.googlesource.com/81736
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Daniel Theophanes <kardianos@gmail.com>
src/database/sql/sql.go