diff --git a/src/box/alter.cc b/src/box/alter.cc index afb02e80a1fff97efb4443baa0f7dec799e12fac..d6522f4046045c2441f2c597316eff53a887feb7 100644 --- a/src/box/alter.cc +++ b/src/box/alter.cc @@ -825,7 +825,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 c721289a54c4463819efc920044762cad2a0287e..8d2875737e00b7756a58ee2e4b9bf05decd39348 100644 --- a/src/box/applier.cc +++ b/src/box/applier.cc @@ -1221,8 +1221,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 7ae524fecc4c04f9e32805db03f10286814e772e..9aa25a7e741fc8263eba1a5d13f10c8429981804 100644 --- a/src/box/lua/init.c +++ b/src/box/lua/init.c @@ -485,9 +485,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. */ @@ -496,13 +496,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); @@ -510,15 +511,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 f409fff6b312c657743c864ff497e9cf7f62b50f..da7005b61c85067b4f3449c0d812cbdbf6a61847 100644 --- a/src/box/txn.c +++ b/src/box/txn.c @@ -355,7 +355,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"); } @@ -704,7 +704,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"); } @@ -733,7 +733,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 03ef60a253605b2e5fd25a3491ce48923120f658..526453aa2e6583be453a4cd031342ff1ff009296 100644 --- a/src/box/txn.h +++ b/src/box/txn.h @@ -891,6 +891,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 f163ff660dcb1814546f3261c9f90f6a6f76a86e..135b3e030debb9c7df7b00b0e5edc49b2604fb26 100644 --- a/src/box/vinyl.c +++ b/src/box/vinyl.c @@ -4373,7 +4373,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