diff --git a/src/box/alter.cc b/src/box/alter.cc index 19eba879634b120aa04319aadcd4e239038a96f4..412f19049c6dcac2cd77973946fdc9095b5c6b47 100644 --- a/src/box/alter.cc +++ b/src/box/alter.cc @@ -868,7 +868,8 @@ struct mh_i32_t *AlterSpaceLock::registry; static int alter_space_commit(struct trigger *trigger, void *event) { - struct txn *txn = (struct txn *) event; + (void)event; + struct txn *txn = in_txn(); struct alter_space *alter = (struct alter_space *) trigger->data; /* * The engine (vinyl) expects us to pass the signature of diff --git a/src/box/applier.cc b/src/box/applier.cc index ab3315298c75903f0b8b7f46b6f1bf1e0e0df7f3..551a7e1d413f499c25ea3e2843dafb62255180ac 100644 --- a/src/box/applier.cc +++ b/src/box/applier.cc @@ -1219,8 +1219,9 @@ applier_rollback_by_wal_io(int64_t signature) static int applier_txn_rollback_cb(struct trigger *trigger, void *event) { - (void) trigger; - struct txn *txn = (struct txn *) event; + (void)trigger; + (void)event; + struct txn *txn = in_txn(); /* * Synchronous transaction rollback due to receiving a * ROLLBACK entry is a normal event and requires no diff --git a/src/box/lua/init.c b/src/box/lua/init.c index a476e8e39527cfd4a654fe55fef1fb1857841fd6..aa65b31adc8ee4a61ced16efc5a43d632031e66b 100644 --- a/src/box/lua/init.c +++ b/src/box/lua/init.c @@ -579,9 +579,9 @@ lbox_txn_iterator_next(struct lua_State *L) } /** - * Open an iterator over the transaction statements. This is a C - * closure and 1 upvalue should be available - id of the - * transaction to iterate over. + * Open an iterator over the transaction statements. This is a C closure and + * 2 upvalues should be available: first is an id of the transaction to iterate + * over, second is the first statement of the iteration. * It returns 3 values which can be used in Lua 'for': iterator * generator function, unused nil and the zero key. */ @@ -590,13 +590,14 @@ lbox_txn_pairs(struct lua_State *L) { int64_t txn_id = luaL_toint64(L, lua_upvalueindex(1)); struct txn *txn = in_txn(); + struct txn_stmt *stmt; + stmt = (struct txn_stmt *)lua_topointer(L, lua_upvalueindex(2)); if (txn == NULL || txn->id != txn_id) { diag_set(ClientError, ER_CURSOR_NO_TRANSACTION); return luaT_error(L); } luaL_pushint64(L, txn_id); - lua_pushlightuserdata(L, stailq_first_entry(&txn->stmts, - struct txn_stmt, next)); + lua_pushlightuserdata(L, stmt); lua_pushcclosure(L, lbox_txn_iterator_next, 2); lua_pushnil(L); lua_pushinteger(L, 0); @@ -604,15 +605,17 @@ lbox_txn_pairs(struct lua_State *L) } /** - * Push an argument for on_commit Lua trigger. The argument is + * Push an argument for on_commit and on_rollback Lua triggers. The argument is * a function to open an iterator over the transaction statements. */ static int lbox_push_txn(struct lua_State *L, void *event) { - struct txn *txn = (struct txn *) event; + struct txn *txn = in_txn(); + struct txn_stmt *stmt = (struct txn_stmt *)event; luaL_pushint64(L, txn->id); - lua_pushcclosure(L, lbox_txn_pairs, 1); + lua_pushlightuserdata(L, stmt); + lua_pushcclosure(L, lbox_txn_pairs, 2); return 1; } diff --git a/src/box/txn.c b/src/box/txn.c index ed8c214df5b013e863f27d7de49211ee04652e28..d0fc7cc5d2e36ef86ef8d4aed276959f86b99154 100644 --- a/src/box/txn.c +++ b/src/box/txn.c @@ -357,7 +357,7 @@ txn_rollback_one_stmt(struct txn *txn, struct txn_stmt *stmt) { if (txn->engine != NULL && stmt->space != NULL) engine_rollback_statement(txn->engine, txn, stmt); - if (stmt->has_triggers && trigger_run(&stmt->on_rollback, txn) != 0) { + if (stmt->has_triggers && trigger_run(&stmt->on_rollback, stmt) != 0) { diag_log(); panic("statement rollback trigger failed"); } @@ -710,7 +710,7 @@ txn_complete_fail(struct txn *txn) if (txn->engine != NULL) engine_rollback(txn->engine, txn); if (txn_has_flag(txn, TXN_HAS_TRIGGERS)) { - if (trigger_run(&txn->on_rollback, txn) != 0) { + if (trigger_run(&txn->on_rollback, txn_first_stmt(txn)) != 0) { diag_log(); panic("transaction rollback trigger failed"); } @@ -739,7 +739,8 @@ txn_complete_success(struct txn *txn) * so that a trigger sees the changes done by previous triggers * (this is vital for DDL). */ - if (trigger_run_reverse(&txn->on_commit, txn) != 0) { + if (trigger_run_reverse(&txn->on_commit, + txn_first_stmt(txn)) != 0) { diag_log(); panic("transaction commit trigger failed"); } diff --git a/src/box/txn.h b/src/box/txn.h index 0750e5f786d75387ca6214d4fb3c17ed15c27860..de669fdc101db0e68d5297f0f60b0973b09aa968 100644 --- a/src/box/txn.h +++ b/src/box/txn.h @@ -909,6 +909,13 @@ txn_is_first_statement(struct txn *txn) return stailq_last(&txn->stmts) == stailq_first(&txn->stmts); } +/** The first statement of the transaction. */ +static inline struct txn_stmt * +txn_first_stmt(struct txn *txn) +{ + return stailq_first_entry(&txn->stmts, struct txn_stmt, next); +} + /** The current statement of the transaction. */ static inline struct txn_stmt * txn_current_stmt(struct txn *txn) diff --git a/src/box/vinyl.c b/src/box/vinyl.c index 4e0669a26885c907e2fdb6ac640a5b916d08f6f9..6d6faf510e7e90e59ccad61c4b92ef1fd7eb84af 100644 --- a/src/box/vinyl.c +++ b/src/box/vinyl.c @@ -4395,7 +4395,8 @@ vinyl_space_build_index(struct space *src_space, struct index *new_index, static int vy_deferred_delete_on_commit(struct trigger *trigger, void *event) { - struct txn *txn = event; + (void)event; + struct txn *txn = in_txn(); struct vy_mem *mem = trigger->data; /* * Update dump_lsn so that we can skip dumped deferred