diff --git a/mdbx.h b/mdbx.h index fa81d503..999016b5 100644 --- a/mdbx.h +++ b/mdbx.h @@ -2771,6 +2771,19 @@ LIBMDBX_API int mdbx_txn_commit(MDBX_txn *txn); * \retval MDBX_EINVAL Transaction handle is NULL. */ LIBMDBX_API int mdbx_txn_abort(MDBX_txn *txn); +/** Marks transaction as broken. + * \ingroup c_transactions + * + * Function keeps the transaction handle and corresponding locks, but it + * is not possible to perform any operations in a broken transaction. + * Broken transaction must then be aborted explicitly later. + * + * \param [in] txn A transaction handle returned by \ref mdbx_txn_begin(). + * + * \see mdbx_txn_abort() \see mdbx_txn_reset() \see mdbx_txn_commit() + * \returns A non-zero error value on failure and 0 on success. */ +LIBMDBX_API int mdbx_txn_break(MDBX_txn *txn); + /** Reset a read-only transaction. * \ingroup c_transactions * diff --git a/src/core.c b/src/core.c index 75cb913a..8ce829d2 100644 --- a/src/core.c +++ b/src/core.c @@ -6850,6 +6850,19 @@ int mdbx_txn_reset(MDBX_txn *txn) { return rc; } +int mdbx_txn_break(MDBX_txn *txn) { + do { + int rc = check_txn(txn, 0); + if (unlikely(rc != MDBX_SUCCESS)) + return rc; + txn->mt_flags |= MDBX_TXN_ERROR; + if (txn->mt_flags & MDBX_TXN_RDONLY) + break; + txn = txn->mt_child; + } while (txn); + return MDBX_SUCCESS; +} + int mdbx_txn_abort(MDBX_txn *txn) { int rc = check_txn(txn, 0); if (unlikely(rc != MDBX_SUCCESS))