Commit 67b42fa7 authored by Kirill Smelkov's avatar Kirill Smelkov

zodbcommit: Don't forget to call tpc_abort on an error

Two-phase commit protocol assumes that after tpc_begin, it will be
either successful tpc_vote + tpc_finish, or tpc_abort. We were not
calling tpc_abort on an error, potentially leaving storage in "commit is
in progress" state on an error.

/reviewed-by @jerome
/reviewed-on !19
parent c59a54ca
# Copyright (C) 2018-2020 Nexedi SA and Contributors. # Copyright (C) 2018-2021 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
...@@ -58,6 +58,8 @@ def zodbcommit(stor, at, txn): ...@@ -58,6 +58,8 @@ def zodbcommit(stor, at, txn):
before = p64(u64(at)+1) before = p64(u64(at)+1)
stor.tpc_begin(txn) stor.tpc_begin(txn)
def _():
for obj in txn.objv: for obj in txn.objv:
data = None # data do be committed - setup vvv data = None # data do be committed - setup vvv
if isinstance(obj, zodbdump.ObjectCopy): if isinstance(obj, zodbdump.ObjectCopy):
...@@ -100,7 +102,12 @@ def zodbcommit(stor, at, txn): ...@@ -100,7 +102,12 @@ def zodbcommit(stor, at, txn):
else: else:
stor.store(obj.oid, serial_prev, data, '', txn) stor.store(obj.oid, serial_prev, data, '', txn)
try:
_()
stor.tpc_vote(txn) stor.tpc_vote(txn)
except:
stor.tpc_abort(txn)
raise
# in ZODB >= 5 tpc_finish returns tid directly, but on ZODB 4 it # in ZODB >= 5 tpc_finish returns tid directly, but on ZODB 4 it
# does not do so. Since we still need to support ZODB 4, utilize tpc_finish # does not do so. Since we still need to support ZODB 4, utilize tpc_finish
......
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