On successful commit of outer transactions, only updates of inner transactions that return status other than YDB_OK or YDB_TP_RESTART are rolled back
Final Release Note
In applications using the C API (and other language APIs that wrap the C API), updates from outer transactions that invoke nested inner transactions which return YDB_TP_ROLLBACK are committed upon a successful transaction commit; updates of inner transactions whose callback functions return any status to ydb_tp_s() / ydb_tp_st() other than YDB_OK or YDB_TP_RESTART are rolled back. Previously, updates from the enclosing transaction were also rolled back, whereas only the updates of the inner transactions should have been rolled back. The workaround was to return YDB_TP_ROLLBACK through all transaction levels to the top application code level outside a transaction, and for that code to re-invoke YottaDB transaction logic. [#550 (closed)]
Description
Transaction rollbacks are handled differently in M code and the C API, as YottaDB controls the runtime environment of M, but does not for C.
In M code, a TROLLBACK can roll a nested transaction back a specified number of nesting levels or to a specific level. After a TROLLBACK, execution continues with the next command after the TROLLBACK.
With the C API (and hence other languages that access YottaDB through the C API), when application logic decides to rollback a transaction, it returns a YDB_TP_ROLLBACK to YottaDB. For example, if the call stack is Application Code 1 → ydb_tp_s() 1 → Application code 2 → ydb_tp_s() 2 → Application code 3 and Application code 3 decides to rollback its transaction, it returns YDB_TP_ROLLBACK to ydb_tp_s() 2, and in turn ydb_tp_s() 2 returns YDB_TP_ROLLBACK to Application code 2.
Application code 2 can continue its execution, and when it decides to commit, it returns a YDB_OK to ydb_tp_s() 1, which commits if it is able to or calls Application code 2 again. When this transaction is committed, it should have the updates from Application code 2 (and any logic it invokes), but no updates from the rolled back transaction of Application code 3. As implemented, it does not have the updates from Application code 2.
The workaround is for Application code 2 to to return YDB_TP_ROLLBACK to ydb_tp_s() 1, which in turn returns that code to Application code 1, which can then restart the transaction.
Draft Release Note
In applications using the C API (and other language APIs that wrap the C API), updates from transactions that invoke nested transactions which return YDB_TP_ROLLBACK are committed upon a successful transaction commit. Previously, updates from the enclosing transaction were also rolled back. The workaround was to return YDB_TP_ROLLBACK through all transaction levels to the top application code level outside a transaction, and for that code to re-invoke YottaDB transaction logic. [#550 (closed)]