diff options
author | Erlend Egeberg Aasland <erlend.aasland@innova.no> | 2021-08-25 10:59:42 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-25 10:59:42 (GMT) |
commit | 7ecd3425d45a37efbc745788dfe21df0286c785a (patch) | |
tree | 5480bf4db64fadf5ad4e2e931464c8278443ea28 /Modules/_sqlite | |
parent | 3df0fc89bc2714f5ef03e36a926bc795dcd5e05a (diff) | |
download | cpython-7ecd3425d45a37efbc745788dfe21df0286c785a.zip cpython-7ecd3425d45a37efbc745788dfe21df0286c785a.tar.gz cpython-7ecd3425d45a37efbc745788dfe21df0286c785a.tar.bz2 |
bpo-27334: roll back transaction if sqlite3 context manager fails to commit (GH-26202)
Co-authored-by: Luca Citi
Co-authored-by: Berker Peksag <berker.peksag@gmail.com>
Diffstat (limited to 'Modules/_sqlite')
-rw-r--r-- | Modules/_sqlite/connection.c | 28 |
1 files changed, 21 insertions, 7 deletions
diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index 8ad5f5f..1bc0455 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -1785,17 +1785,31 @@ pysqlite_connection_exit_impl(pysqlite_Connection *self, PyObject *exc_type, PyObject *exc_value, PyObject *exc_tb) /*[clinic end generated code: output=0705200e9321202a input=bd66f1532c9c54a7]*/ { - const char* method_name; + int commit = 0; PyObject* result; if (exc_type == Py_None && exc_value == Py_None && exc_tb == Py_None) { - method_name = "commit"; - } else { - method_name = "rollback"; + commit = 1; + result = pysqlite_connection_commit_impl(self); } - - result = PyObject_CallMethod((PyObject*)self, method_name, NULL); - if (!result) { + else { + result = pysqlite_connection_rollback_impl(self); + } + + if (result == NULL) { + if (commit) { + /* Commit failed; try to rollback in order to unlock the database. + * If rollback also fails, chain the exceptions. */ + PyObject *exc, *val, *tb; + PyErr_Fetch(&exc, &val, &tb); + result = pysqlite_connection_rollback_impl(self); + if (result == NULL) { + _PyErr_ChainExceptions(exc, val, tb); + } + else { + PyErr_Restore(exc, val, tb); + } + } return NULL; } Py_DECREF(result); |