diff --git a/src/box/alter.cc b/src/box/alter.cc
index 7a1b19296c1c352d9e5d9a5ad0055d520f68bef1..297b50b097927fa7ac2ea6981c4f51680d6a3718 100644
--- a/src/box/alter.cc
+++ b/src/box/alter.cc
@@ -512,7 +512,7 @@ ModifySpace::prepare(struct alter_space *alter)
 	}
 
 	EngineFactory *factory = alter->old_space->engine->factory;
-	if (def.temporary && !engine_can_be_temporary(factory->id)) {
+	if (def.temporary && !engine_can_be_temporary(factory->flags)) {
 		tnt_raise(ClientError, ER_ALTER_SPACE,
 			  (unsigned) def.id,
 			  "space does not support temporary flag");
diff --git a/src/box/engine.h b/src/box/engine.h
index 1fdfe489f03441d91d900cccbd895ffc9c41021f..affabcd79660be46c3017f48d1ca8eadd1a16c38 100644
--- a/src/box/engine.h
+++ b/src/box/engine.h
@@ -186,24 +186,21 @@ EngineFactory *engine_find_id(uint32_t);
 void engine_shutdown();
 
 static inline bool
-engine_transactional(uint32_t id)
+engine_transactional(uint32_t flags)
 {
-	assert(id);
-	return engine_flags[id] & ENGINE_TRANSACTIONAL;
+	return flags & ENGINE_TRANSACTIONAL;
 }
 
 static inline bool
-engine_no_yield(uint32_t id)
+engine_no_yield(uint32_t flags)
 {
-	assert(id);
-	return engine_flags[id] & ENGINE_NO_YIELD;
+	return flags & ENGINE_NO_YIELD;
 }
 
 static inline bool
-engine_can_be_temporary(uint32_t id)
+engine_can_be_temporary(uint32_t flags)
 {
-	assert(id);
-	return engine_flags[id] & ENGINE_CAN_BE_TEMPORARY;
+	return flags & ENGINE_CAN_BE_TEMPORARY;
 }
 
 static inline uint32_t
diff --git a/src/box/engine_memtx.cc b/src/box/engine_memtx.cc
index f1c363fa6ad6af98a46618afa248fb44462aa196..a9dd47e1dbcf1c56e2cdcd04db9fd398878556b4 100644
--- a/src/box/engine_memtx.cc
+++ b/src/box/engine_memtx.cc
@@ -26,10 +26,10 @@
  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
-#include "txn.h"
 #include "tuple.h"
 #include "engine.h"
 #include "engine_memtx.h"
+#include "txn.h"
 #include "index.h"
 #include "hash_index.h"
 #include "tree_index.h"
diff --git a/src/box/engine_sophia.cc b/src/box/engine_sophia.cc
index 7b8cea78fb70865d193104992f144171a56b9028..d6959c4f74241aeb4ce9608ceeadc60803e2d46e 100644
--- a/src/box/engine_sophia.cc
+++ b/src/box/engine_sophia.cc
@@ -28,11 +28,11 @@
  */
 #include "cfg.h"
 #include "xrow.h"
-#include "txn.h"
 #include "tuple.h"
 #include "scoped_guard.h"
 #include "engine.h"
 #include "engine_sophia.h"
+#include "txn.h"
 #include "index.h"
 #include "sophia_index.h"
 #include "space.h"
diff --git a/src/box/key_def.cc b/src/box/key_def.cc
index 42283d80aeb7268d526eb517a7e283ea9d881780..311e1e2d3949afe8057cb8100189af629638d007 100644
--- a/src/box/key_def.cc
+++ b/src/box/key_def.cc
@@ -227,7 +227,7 @@ space_def_check(struct space_def *def, uint32_t namelen, uint32_t engine_namelen
 
 	if (def->temporary) {
 		EngineFactory *factory = engine_find(def->engine_name);
-		if (! engine_can_be_temporary(factory->id))
+		if (! engine_can_be_temporary(factory->flags))
 			tnt_raise(ClientError, ER_ALTER_SPACE,
 			         (unsigned) def->id,
 			         "space does not support temporary flag");
diff --git a/src/box/lua/call.cc b/src/box/lua/call.cc
index 538bbe29453e27ce2abf0988bef8c6128921a7a5..e1683d7557f90028329a2f7398f75237f8b2dd1a 100644
--- a/src/box/lua/call.cc
+++ b/src/box/lua/call.cc
@@ -46,6 +46,7 @@
 #include "box/box.h"
 #include "box/port.h"
 #include "box/request.h"
+#include "box/engine.h"
 #include "box/txn.h"
 #include "box/access.h"
 #include "box/schema.h"
diff --git a/src/box/request.cc b/src/box/request.cc
index 909d56833012af95a19573778684facbf9dca76e..5cf0bb9ed49c6c9e6129762b9c133ac81e015eaf 100644
--- a/src/box/request.cc
+++ b/src/box/request.cc
@@ -27,6 +27,7 @@
  * SUCH DAMAGE.
  */
 #include "request.h"
+#include "engine.h"
 #include "txn.h"
 #include "tuple.h"
 #include "index.h"
diff --git a/src/box/txn.cc b/src/box/txn.cc
index c81d5f56066688f919e83b4d4d20184162866a9a..25ade4a04c4b25a8e595c2d75495e10e9723ef63 100644
--- a/src/box/txn.cc
+++ b/src/box/txn.cc
@@ -26,6 +26,7 @@
  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
+#include "engine.h"
 #include "txn.h"
 #include "box.h"
 #include "tuple.h"
@@ -95,7 +96,7 @@ txn_replace(struct txn *txn, struct space *space,
 	 */
 	if (txn->autocommit == false) {
 		if (txn->n_stmts == 1) {
-			if (engine_no_yield(txn->engine)) {
+			if (engine_no_yield(txn->engine->flags)) {
 				trigger_add(&fiber()->on_yield,
 					    &txn->fiber_on_yield);
 				trigger_add(&fiber()->on_stop,
@@ -173,47 +174,20 @@ txn_engine_begin_stmt(struct txn *txn, struct space *space)
 	 */
 	EngineFactory *factory = space->engine->factory;
 	if (txn->n_stmts == 1) {
-		txn->engine = factory->id;
+		txn->engine = factory;
 		if (txn->autocommit == false) {
-			if (! engine_transactional(txn->engine))
+			if (! engine_transactional(txn->engine->flags))
 				tnt_raise(ClientError, ER_UNSUPPORTED,
 				          space->def.engine_name, "transactions");
 		}
 		factory->begin(txn, space);
 		return;
 	}
-	if (txn->engine != engine_id(space->engine))
+	if (txn->engine->id != engine_id(space->engine))
 		tnt_raise(ClientError, ER_CROSS_ENGINE_TRANSACTION);
 	factory->begin_stmt(txn, space);
 }
 
-static inline void
-txn_engine_commit(struct txn *txn)
-{
-	if (txn->engine == 0)
-		return;
-	EngineFactory *factory = engine_find_id(txn->engine);
-	factory->commit(txn);
-}
-
-static inline void
-txn_engine_rollback(struct txn *txn)
-{
-	if (txn->engine == 0)
-		return;
-	EngineFactory *factory = engine_find_id(txn->engine);
-	factory->rollback(txn);
-}
-
-static inline void
-txn_engine_finish_stmt(struct txn *txn, struct txn_stmt *stmt)
-{
-	if (txn->engine == 0)
-		return;
-	EngineFactory *factory = engine_find_id(txn->engine);
-	factory->finish_stmt(stmt);
-}
-
 void
 txn_commit_stmt(struct txn *txn, struct port *port)
 {
@@ -262,7 +236,8 @@ txn_commit(struct txn *txn)
 		if (res)
 			tnt_raise(LoggedError, ER_WAL_IO);
 	}
-	txn_engine_commit(txn);
+	if (txn->engine)
+		txn->engine->commit(txn);
 	trigger_run(&txn->on_commit, txn); /* must not throw. */
 }
 
@@ -273,7 +248,7 @@ txn_finish(struct txn *txn)
 	rlist_foreach_entry(stmt, &txn->stmts, next) {
 		if (stmt->old_tuple)
 			tuple_unref(stmt->old_tuple);
-		txn_engine_finish_stmt(txn, stmt);
+		txn->engine->finish_stmt(stmt);
 	}
 	TRASH(txn);
 	/** Free volatile txn memory. */
@@ -313,7 +288,8 @@ txn_rollback()
 	struct txn *txn = in_txn();
 	if (txn == NULL)
 		return;
-	txn_engine_rollback(txn);
+	if (txn->engine)
+		txn->engine->rollback(txn);
 	trigger_run(&txn->on_rollback, txn); /* must not throw. */
 	struct txn_stmt *stmt;
 	rlist_foreach_entry(stmt, &txn->stmts, next) {
diff --git a/src/box/txn.h b/src/box/txn.h
index 89fe56559605a3c9c7dcb8e9c4dc79d963f9d1b6..6477374ac8f468575308879473aa20e3e9b7d6b1 100644
--- a/src/box/txn.h
+++ b/src/box/txn.h
@@ -67,8 +67,8 @@ struct txn {
 	 * (statement end causes an automatic transaction commit).
 	 */
 	bool autocommit;
-	/** Id of the engine involved in multi-statement transaction. */
-	uint8_t engine;
+	/** Engine involved in multi-statement transaction. */
+	EngineFactory *engine;
 	/** Triggers on fiber yield and stop to abort transaction for in-memory engine */
 	struct trigger fiber_on_yield, fiber_on_stop;
 };