Commit 7e0c944f authored by Kirill Smelkov's avatar Kirill Smelkov

go/transaction: Fix Abort to wait for synchronizers completion

There was a thinko in transaction.Abort - it was spawning synchronizers
under a waitgroup, but wg.Wait() call was forgotten. This way, e.g. in
ZODB if a transaction was aborted, corresponding connection could be not
yet returned back into DB pool.

Fix it.

Test is TODO for the time when, hopefully, tracetest is generally ready.
parent a9e2badf
// Copyright (C) 2018 Nexedi SA and Contributors. // Copyright (C) 2018-2019 Nexedi SA and Contributors.
// Kirill Smelkov <kirr@nexedi.com> // Kirill Smelkov <kirr@nexedi.com>
// //
// This program is free software: you can Use, Study, Modify and Redistribute // This program is free software: you can Use, Study, Modify and Redistribute
// it under the terms of the GNU General Public License version 3, or (at your // it under the terms of the GNU General Public License version 3, or (at your
...@@ -160,6 +160,7 @@ func (txn *transaction) Abort() { ...@@ -160,6 +160,7 @@ func (txn *transaction) Abort() {
syncv[i].AfterCompletion(txn) syncv[i].AfterCompletion(txn)
}() }()
} }
wg.Wait()
// XXX return error? // XXX return error?
} }
......
// Copyright (C) 2018 Nexedi SA and Contributors. // Copyright (C) 2018-2019 Nexedi SA and Contributors.
// Kirill Smelkov <kirr@nexedi.com> // Kirill Smelkov <kirr@nexedi.com>
// //
// This program is free software: you can Use, Study, Modify and Redistribute // This program is free software: you can Use, Study, Modify and Redistribute
// it under the terms of the GNU General Public License version 3, or (at your // it under the terms of the GNU General Public License version 3, or (at your
...@@ -98,7 +98,17 @@ func TestAbort(t *testing.T) { ...@@ -98,7 +98,17 @@ func TestAbort(t *testing.T) {
dm.Modify() dm.Modify()
// XXX +sync // XXX +sync
/* XXX test Abort not waiting for AfterCompletion via tracetest (with injected δt shakes):
txn.RegisterSync(AfterCompletion: {eAfterCompletion})
go func() {
eAbortPre
txn.Abort()
eAbortPost
}()
expect(eAbortPre, eAfterCompletion, eAbortPost)
*/
txn.Abort() txn.Abort()
if !(dm.nabort == 1 && txn.Status() == Aborted) { if !(dm.nabort == 1 && txn.Status() == Aborted) {
t.Fatalf("abort: nabort=%d; txn.Status=%v", dm.nabort, txn.Status()) t.Fatalf("abort: nabort=%d; txn.Status=%v", dm.nabort, txn.Status())
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment