diff --git a/src/box/lua/call.cc b/src/box/lua/call.cc
index 8c27328020cdb89423aa144ec6bee1be5a757473..cc92cf7b75fbfe8de9d24636bd4a1fdb4ef12c24 100644
--- a/src/box/lua/call.cc
+++ b/src/box/lua/call.cc
@@ -360,10 +360,15 @@ lbox_commit(lua_State * /* L */)
 	 * Do nothing if transaction is not started,
 	 * it's the same as BEGIN + COMMIT.
 	*/
-	if (txn) {
+	if (! txn)
+		return 0;
+	try {
 		txn_commit(txn);
-		txn_finish(txn);
+	} catch (...) {
+		txn_rollback();
+		throw;
 	}
+	txn_finish(txn);
 	return 0;
 }
 
@@ -615,6 +620,13 @@ execute_call(lua_State *L, struct request *request, struct obuf *out)
 void
 box_lua_call(struct request *request, struct obuf *out)
 {
+	auto txn_guard = make_scoped_guard([=] {
+		struct txn *txn = in_txn();
+		if (txn) {
+			say_warn("transaction is active at CALL return");
+			txn_rollback();
+		}
+	});
 	lua_State *L = NULL;
 	try {
 		L = lua_newthread(tarantool_L);
diff --git a/src/box/lua/load_cfg.lua b/src/box/lua/load_cfg.lua
index be134f513847b37597850c49776af67349e09f96..55ee8e14fdada0b749ba62297ed5873f90e3231a 100644
--- a/src/box/lua/load_cfg.lua
+++ b/src/box/lua/load_cfg.lua
@@ -21,7 +21,8 @@ local default_sophia_cfg = {
     memory_limit = 0,
     threads      = 5,
     node_size    = 134217728,
-    page_size    = 131072
+    page_size    = 131072,
+    compression  = "none"
 }
 
 -- all available options
@@ -65,7 +66,8 @@ local sophia_template_cfg = {
     memory_limit = 'number',
     threads      = 'number',
     node_size    = 'number',
-    page_size    = 'number'
+    page_size    = 'number',
+    compression  = 'string'
 }
 
 -- types of available options
diff --git a/src/box/sophia_engine.cc b/src/box/sophia_engine.cc
index 2d56e7c152246b2cf4ede600aae9388678f9e961..8f294a7687bd69836ac3a1f0bc630cdb8dd89b87 100644
--- a/src/box/sophia_engine.cc
+++ b/src/box/sophia_engine.cc
@@ -76,6 +76,15 @@ void sophia_info(void (*callback)(const char*, const char*, void*), void *arg)
 	sp_destroy(cur);
 }
 
+static struct tuple *
+sophia_replace(struct space *space, struct tuple *old_tuple,
+               struct tuple *new_tuple,
+               enum dup_replace_mode mode)
+{
+	Index *index = index_find(space, 0);
+	return index->replace(old_tuple, new_tuple, mode);
+}
+
 struct SophiaSpace: public Handler {
 	SophiaSpace(Engine*);
 };
@@ -88,8 +97,7 @@ static void
 sophia_recovery_end(struct space *space)
 {
 	engine_recovery *r = &space->handler->recovery;
-	r->state   = READY_ALL_KEYS;
-	r->replace = sophia_replace;
+	r->state = READY_ALL_KEYS;
 	r->recover = space_noop;
 }
 
@@ -97,7 +105,7 @@ static void
 sophia_recovery_end_snapshot(struct space *space)
 {
 	engine_recovery *r = &space->handler->recovery;
-	r->state   = READY_PRIMARY_KEY;
+	r->state = READY_PRIMARY_KEY;
 	r->recover = sophia_recovery_end;
 }
 
@@ -118,7 +126,7 @@ SophiaEngine::SophiaEngine()
 	env = NULL;
 	recovery.state   = READY_NO_KEYS;
 	recovery.recover = sophia_recovery_begin_snapshot;
-	recovery.replace = sophia_replace_recover;
+	recovery.replace = sophia_replace;
 }
 
 void
@@ -148,10 +156,20 @@ SophiaEngine::open()
 	return new SophiaSpace(this);
 }
 
+static inline void
+sophia_snapshot_recover(void *env, int64_t lsn);
+
 void
 SophiaEngine::end_recover_snapshot()
 {
-	recovery.replace = sophia_replace_recover;
+	/* create snapshot reference after tarantool
+	 * recovery, to ensure correct ref counting
+	 * with spaces involved in snapshot. */
+	if (m_checkpoint_lsn >= 0) {
+		sophia_snapshot_recover(env, m_checkpoint_lsn);
+		m_prev_checkpoint_lsn = m_checkpoint_lsn;
+		m_checkpoint_lsn = -1;
+	}
 	recovery.recover = sophia_recovery_end_snapshot;
 }
 
@@ -237,29 +255,17 @@ SophiaEngine::join(Relay *relay)
 	sp_destroy(db_cursor);
 }
 
-static inline void
-sophia_snapshot_recover(void *env, int64_t lsn);
-
 void
 SophiaEngine::end_recovery()
 {
 	if (recovery_complete)
 		return;
-	/* create snapshot reference after tarantool
-	 * recovery, to ensure correct ref
-	 * counting */
-	if (m_checkpoint_lsn >= 0) {
-		sophia_snapshot_recover(env, m_checkpoint_lsn);
-		m_prev_checkpoint_lsn = m_checkpoint_lsn;
-		m_checkpoint_lsn = -1;
-	}
 	/* complete two-phase recovery */
 	int rc = sp_open(env);
 	if (rc == -1)
 		sophia_raise(env);
-	recovery.state   = READY_NO_KEYS;
-	recovery.replace = sophia_replace;
-	recovery.recover = space_noop;
+	recovery.state    = READY_NO_KEYS;
+	recovery.recover  = space_noop;
 	recovery_complete = 1;
 }
 
@@ -377,8 +383,9 @@ SophiaEngine::commit(struct txn *txn)
 	if (rc == -1)
 		sophia_raise(env);
 	rc = sp_commit(txn->engine_tx);
-	if (rc == -1)
+	if (rc == -1) {
 		sophia_raise(env);
+	}
 	assert(rc == 0);
 }
 
diff --git a/src/box/sophia_index.cc b/src/box/sophia_index.cc
index d81d2b6ca21575136899f70749e3f34db79535a7..e7b47577c10c105d0e5f24447167cdd7996f5ca3 100644
--- a/src/box/sophia_index.cc
+++ b/src/box/sophia_index.cc
@@ -78,38 +78,6 @@ sophia_index_get(void *env, void *db, void *tx, const char *key, size_t keysize,
 	return tuple_new(format, (char*)value, (char*)value + valuesize);
 }
 
-struct tuple*
-sophia_replace_recover(struct space *space,
-                       struct tuple *old_tuple, struct tuple *new_tuple,
-                       enum dup_replace_mode)
-{
-	SophiaIndex *index = (SophiaIndex*)index_find(space, 0);
-	struct txn *txn = in_txn();
-	assert(txn != NULL && txn->engine_tx != NULL);
-	int rc;
-	if (old_tuple) {
-		rc = sophia_index_stmt(txn->engine_tx, index->db, 1,
-		                       index->key_def,
-		                       old_tuple);
-	} else {
-		rc = sophia_index_stmt(txn->engine_tx, index->db, 0,
-		                       index->key_def,
-		                       new_tuple);
-	}
-	if (rc == -1)
-		sophia_raise(index->env);
-	return NULL;
-}
-
-struct tuple *
-sophia_replace(struct space *space,
-               struct tuple *old_tuple, struct tuple *new_tuple,
-               enum dup_replace_mode mode)
-{
-	Index *index = index_find(space, 0);
-	return index->replace(old_tuple, new_tuple, mode);
-}
-
 static inline int
 sophia_index_compare(char *a, size_t asz __attribute__((unused)),
                      char *b, size_t bsz __attribute__((unused)),
@@ -139,6 +107,8 @@ sophia_configure(struct space *space, struct key_def *key_def)
 	snprintf(pointer, sizeof(pointer), "pointer: %p", (void*)sophia_index_compare);
 	snprintf(pointer_arg, sizeof(pointer_arg), "pointer: %p", (void*)key_def);
 	sp_set(c, name, pointer, pointer_arg);
+	snprintf(name, sizeof(name), "db.%" PRIu32 ".compression", key_def->space_id);
+	sp_set(c, name, cfg_gets("sophia.compression"));
 	snprintf(name, sizeof(name), "db.%" PRIu32, key_def->space_id);
 	void *db = sp_get(c, name);
 	if (db == NULL)
@@ -166,16 +136,6 @@ SophiaIndex::SophiaIndex(struct key_def *key_def_arg __attribute__((unused)))
 	tuple_format_ref(space->format, 1);
 }
 
-void
-sophia_complete_recovery(struct space *space)
-{
-	SophiaIndex *index = (SophiaIndex*)index_find(space, 0);
-	assert(space->handler->recovery.recover == space_noop);
-	int rc = sp_open(index->db);
-	if (rc == -1)
-		sophia_raise(index->env);
-}
-
 SophiaIndex::~SophiaIndex()
 {
 	if (m_position != NULL) {
diff --git a/src/box/sophia_index.h b/src/box/sophia_index.h
index f1d2752c6372d25ffcc831bd8f721a219f404573..8a9bacc0c08bc09bc958a47302e05bf003a1c5bd 100644
--- a/src/box/sophia_index.h
+++ b/src/box/sophia_index.h
@@ -52,17 +52,4 @@ class SophiaIndex: public Index {
 	void *db;
 };
 
-struct tuple *
-sophia_replace_recover(struct space*,
-                       struct tuple*, struct tuple*,
-                       enum dup_replace_mode);
-
-struct tuple *
-sophia_replace(struct space*,
-               struct tuple*, struct tuple*,
-               enum dup_replace_mode);
-
-void
-sophia_complete_recovery(struct space*);
-
 #endif /* TARANTOOL_BOX_SOPHIA_INDEX_H_INCLUDED */
diff --git a/src/box/txn.cc b/src/box/txn.cc
index 30c04c3aa0d5ed065fe4fcb57212dca9a77f7114..3d4ae07f2d6d4cf15cf84c081c172e5f9ebb9cb7 100644
--- a/src/box/txn.cc
+++ b/src/box/txn.cc
@@ -208,6 +208,14 @@ txn_commit(struct txn *txn)
 	struct txn_stmt *stmt;
 	/* if (!txn->autocommit && txn->n_stmts && engine_no_yield(txn->engine)) */
 
+	/* xxx: temporary workaround to handle transaction
+	 *      conflicts with sophia.
+	 */
+	if (txn->engine) {
+		txn->engine->commit(txn);
+		txn->engine_tx = NULL;
+	}
+
 	trigger_clear(&txn->fiber_on_yield);
 	trigger_clear(&txn->fiber_on_stop);
 
@@ -229,8 +237,10 @@ txn_commit(struct txn *txn)
 			tnt_raise(LoggedError, ER_WAL_IO);
 		txn->signature = res;
 	}
+	/*
 	if (txn->engine)
 		txn->engine->commit(txn);
+	*/
 	trigger_run(&txn->on_commit, txn); /* must not throw. */
 }
 
diff --git a/test/box/admin.result b/test/box/admin.result
index 807cff8b1fdc2191de54ab3bfe0745a8b11243df..973347aa1bf609cbebd3b827727fad26fa23c4a6 100644
--- a/test/box/admin.result
+++ b/test/box/admin.result
@@ -26,9 +26,10 @@ box.cfg
   slab_alloc_arena: 0.1
   sophia:
     page_size: 131072
+    memory_limit: 0
     threads: 5
     node_size: 134217728
-    memory_limit: 0
+    compression: none
   listen: <uri>
   logger_nonblock: true
   snap_dir: .
diff --git a/test/box/cfg.result b/test/box/cfg.result
index 61e12fb73d441be2a8f7e3918be35412a7201ef0..fc615be3ed65375fb4c314c964cfb8460d8efa40 100644
--- a/test/box/cfg.result
+++ b/test/box/cfg.result
@@ -2,7 +2,7 @@
 --# push filter 'admin: .*' to 'admin: <uri>'
 box.cfg.nosuchoption = 1
 ---
-- error: '[string "-- load_cfg.lua - internal file..."]:260: Attempt to modify a read-only
+- error: '[string "-- load_cfg.lua - internal file..."]:262: Attempt to modify a read-only
     table'
 ...
 t = {} for k,v in pairs(box.cfg) do if type(v) ~= 'table' and type(v) ~= 'function' then table.insert(t, k..': '..tostring(v)) end end
@@ -36,7 +36,7 @@ t
 -- must be read-only
 box.cfg()
 ---
-- error: '[string "-- load_cfg.lua - internal file..."]:206: bad argument #1 to ''pairs''
+- error: '[string "-- load_cfg.lua - internal file..."]:208: bad argument #1 to ''pairs''
     (table expected, got nil)'
 ...
 t = {} for k,v in pairs(box.cfg) do if type(v) ~= 'table' and type(v) ~= 'function' then table.insert(t, k..': '..tostring(v)) end end
@@ -70,23 +70,23 @@ t
 -- check that cfg with unexpected parameter fails.
 box.cfg{sherlock = 'holmes'}
 ---
-- error: '[string "-- load_cfg.lua - internal file..."]:162: Error: cfg parameter
+- error: '[string "-- load_cfg.lua - internal file..."]:164: Error: cfg parameter
     ''sherlock'' is unexpected'
 ...
 -- check that cfg with unexpected type of parameter failes
 box.cfg{listen = {}}
 ---
-- error: '[string "-- load_cfg.lua - internal file..."]:182: Error: cfg parameter
+- error: '[string "-- load_cfg.lua - internal file..."]:184: Error: cfg parameter
     ''listen'' should be one of types: string, number'
 ...
 box.cfg{wal_dir = 0}
 ---
-- error: '[string "-- load_cfg.lua - internal file..."]:176: Error: cfg parameter
+- error: '[string "-- load_cfg.lua - internal file..."]:178: Error: cfg parameter
     ''wal_dir'' should be of type string'
 ...
 box.cfg{coredump = 'true'}
 ---
-- error: '[string "-- load_cfg.lua - internal file..."]:176: Error: cfg parameter
+- error: '[string "-- load_cfg.lua - internal file..."]:178: Error: cfg parameter
     ''coredump'' should be of type boolean'
 ...
 --------------------------------------------------------------------------------
@@ -94,17 +94,17 @@ box.cfg{coredump = 'true'}
 --------------------------------------------------------------------------------
 box.cfg{slab_alloc_arena = "100500"}
 ---
-- error: '[string "-- load_cfg.lua - internal file..."]:176: Error: cfg parameter
+- error: '[string "-- load_cfg.lua - internal file..."]:178: Error: cfg parameter
     ''slab_alloc_arena'' should be of type number'
 ...
 box.cfg{sophia = "sophia"}
 ---
-- error: '[string "-- load_cfg.lua - internal file..."]:170: Error: cfg parameter
+- error: '[string "-- load_cfg.lua - internal file..."]:172: Error: cfg parameter
     ''sophia'' should be a table'
 ...
 box.cfg{sophia = {threads = "threads"}}
 ---
-- error: '[string "-- load_cfg.lua - internal file..."]:176: Error: cfg parameter
+- error: '[string "-- load_cfg.lua - internal file..."]:178: Error: cfg parameter
     ''sophia.threads'' should be of type number'
 ...
 --------------------------------------------------------------------------------
diff --git a/test/sophia/options.result b/test/sophia/options.result
index 75c23ee4a8d5f129793fca2178484888994edce6..4249fd3862eb027730828d2108c946b35d499774 100644
--- a/test/sophia/options.result
+++ b/test/sophia/options.result
@@ -1,9 +1,10 @@
 box.cfg.sophia
 ---
 - page_size: 131072
+  memory_limit: 0
   threads: 0
   node_size: 134217728
-  memory_limit: 0
+  compression: none
 ...
 box.cfg.sophia.threads = 3
 ---
diff --git a/third_party/sophia b/third_party/sophia
index d7010473cfe8ceb7b1254183a77d286aa0cd3b11..68ce375fb75f9194edf967d96d0ff5dc04f3724f 160000
--- a/third_party/sophia
+++ b/third_party/sophia
@@ -1 +1 @@
-Subproject commit d7010473cfe8ceb7b1254183a77d286aa0cd3b11
+Subproject commit 68ce375fb75f9194edf967d96d0ff5dc04f3724f