diff --git a/src/box/engine.cc b/src/box/engine.cc index 338142a293ed2b80a1ccde6cefa53af58b56373a..20c5d92c85fa7fd3f946ba879ef8313b8c7945cc 100644 --- a/src/box/engine.cc +++ b/src/box/engine.cc @@ -48,6 +48,9 @@ void Engine::init() void Engine::beginStatement(struct txn *) {} +void Engine::prepare(struct txn *) +{} + void Engine::commit(struct txn *) {} diff --git a/src/box/engine.h b/src/box/engine.h index d64ed7739985a228779fb246f43ab56889c9117f..a4f2962015cfa2f3143c195c9a072c9779c63230 100644 --- a/src/box/engine.h +++ b/src/box/engine.h @@ -115,6 +115,7 @@ class Engine: public Object { * statement. */ virtual void beginStatement(struct txn *); + virtual void prepare(struct txn *); virtual void commit(struct txn *); virtual void rollbackStatement(struct txn_stmt *); virtual void rollback(struct txn *); diff --git a/src/box/sophia_engine.cc b/src/box/sophia_engine.cc index d17197b3fda20e5d3e24bf94aa8b763459c20b06..7f26646c9b534ca5fbe3f0875b1edae041467c5c 100644 --- a/src/box/sophia_engine.cc +++ b/src/box/sophia_engine.cc @@ -310,36 +310,35 @@ SophiaEngine::beginStatement(struct txn *txn) } void -SophiaEngine::commit(struct txn *txn) +SophiaEngine::prepare(struct txn *txn) { - if (txn->engine_tx == NULL) - return; - auto scoped_guard = make_scoped_guard([=] { - txn->engine_tx = NULL; - }); - /* commit transaction using transaction - * commit signature */ - assert(txn->signature >= 0); - int rc = sp_prepare(txn->engine_tx, txn->signature); + int rc = sp_prepare(txn->engine_tx); switch (rc) { - case 0: - break; case 1: /* rollback */ - tnt_raise(ClientError, ER_TRANSACTION_CONFLICT); - break; + txn->engine_tx = NULL; case 2: /* lock */ - sp_destroy(txn->engine_tx); tnt_raise(ClientError, ER_TRANSACTION_CONFLICT); break; case -1: sophia_raise(env); break; } - rc = sp_commit(txn->engine_tx); +} + +void +SophiaEngine::commit(struct txn *txn) +{ + if (txn->engine_tx == NULL) + return; + /* commit transaction using transaction + * commit signature */ + assert(txn->signature >= 0); + int rc = sp_commit(txn->engine_tx, txn->signature); if (rc == -1) { panic("sophia commit failed: txn->signature = %" PRIu64, txn->signature); } + txn->engine_tx = NULL; } void @@ -351,8 +350,10 @@ SophiaEngine::rollbackStatement(struct txn_stmt *) void SophiaEngine::rollback(struct txn *txn) { - if (txn->engine_tx) + if (txn->engine_tx) { sp_destroy(txn->engine_tx); + txn->engine_tx = NULL; + } } void diff --git a/src/box/sophia_engine.h b/src/box/sophia_engine.h index ab78441c59e92dc1df6b8816ba3fc9e74aaa4319..b36a6ea6ec338d4133cff1947ba1a2b5b0ea7b8b 100644 --- a/src/box/sophia_engine.h +++ b/src/box/sophia_engine.h @@ -38,6 +38,7 @@ struct SophiaEngine: public Engine { virtual void dropIndex(Index*); virtual void keydefCheck(struct space *space, struct key_def *f); virtual void beginStatement(struct txn *txn); + virtual void prepare(struct txn *txn); virtual void commit(struct txn *txn); virtual void rollbackStatement(struct txn_stmt *stmt); virtual void rollback(struct txn *txn); diff --git a/src/box/txn.cc b/src/box/txn.cc index ab5f2d4a33faafbc748eaded6cdeeb021d022b07..ca69ec72f62da8a29579486e2ab7d8ba0c5630d4 100644 --- a/src/box/txn.cc +++ b/src/box/txn.cc @@ -177,6 +177,10 @@ txn_commit(struct txn *txn) trigger_clear(&txn->fiber_on_yield); trigger_clear(&txn->fiber_on_stop); + /* Do transaction conflict resolving */ + if (txn->engine) + txn->engine->prepare(txn); + rlist_foreach_entry(stmt, &txn->stmts, next) { if ((!stmt->old_tuple && !stmt->new_tuple) || space_is_temporary(stmt->space)) @@ -197,7 +201,6 @@ txn_commit(struct txn *txn) } trigger_run(&txn->on_commit, txn); /* must not throw. */ - /* xxx: engine commit may throw on conflict or error */ if (txn->engine) txn->engine->commit(txn); TRASH(txn); diff --git a/test/long_run/box.lua b/test/long_run/box.lua index 9cac3cadb04b8c84bac41b1ee5c2828523dc3aba..0e524ae28f0dd3d696519edf8d88a69f4eba8d36 100644 --- a/test/long_run/box.lua +++ b/test/long_run/box.lua @@ -2,6 +2,7 @@ require('suite') +os.execute("rm -rf sophia_test") os.execute("mkdir -p sophia_test") local sophia = { diff --git a/test/long_run/memtx_dru.result b/test/long_run/memtx_delete_replace_update.result similarity index 100% rename from test/long_run/memtx_dru.result rename to test/long_run/memtx_delete_replace_update.result diff --git a/test/long_run/memtx_dru.test.lua b/test/long_run/memtx_delete_replace_update.test.lua similarity index 100% rename from test/long_run/memtx_dru.test.lua rename to test/long_run/memtx_delete_replace_update.test.lua diff --git a/test/long_run/sophia_dru.result b/test/long_run/sophia_delete_replace_update.result similarity index 100% rename from test/long_run/sophia_dru.result rename to test/long_run/sophia_delete_replace_update.result diff --git a/test/long_run/sophia_dru.test.lua b/test/long_run/sophia_delete_replace_update.test.lua similarity index 100% rename from test/long_run/sophia_dru.test.lua rename to test/long_run/sophia_delete_replace_update.test.lua diff --git a/test/long_run/suite.ini b/test/long_run/suite.ini index 747c518ba7175e7a5b82166d71032940348b49f2..60e532919c4961f22d26862ae1cdb71d050f6b11 100644 --- a/test/long_run/suite.ini +++ b/test/long_run/suite.ini @@ -2,7 +2,7 @@ core = tarantool description = long running tests script = box.lua -disabled = memtx_dru.test.lua sophia_dru.test.lua memtx_delete_insert.test.lua sophia_delete_insert.test.lua +disabled = memtx_delete_replace_update.test.lua sophia_delete_replace_update.test.lua memtx_delete_insert.test.lua sophia_delete_insert.test.lua valgrind_disabled = release_disabled = lua_libs = suite.lua diff --git a/test/sophia/conflict.lua b/test/sophia/conflict.lua new file mode 100644 index 0000000000000000000000000000000000000000..d418119a39ff9cbfa2c0fefd1773625eae889f26 --- /dev/null +++ b/test/sophia/conflict.lua @@ -0,0 +1,22 @@ + +function test_conflict() + s = box.schema.space.create('tester', {engine='sophia'}); + i = s:create_index('sophia_index', {type = 'tree', parts = {1, 'STR'}}); + + commits = 0 + function conflict() + box.begin() + s:replace({'test'}) + box.commit() + commits = commits + 1 + end; + + fiber = require('fiber'); + f0 = fiber.create(conflict); + f1 = fiber.create(conflict); -- conflict + fiber.sleep(0); + + s:drop(); + sophia_schedule(); + return commits +end diff --git a/test/sophia/conflict.result b/test/sophia/conflict.result new file mode 100644 index 0000000000000000000000000000000000000000..c58114ceee84ad5916dc7f57f8e24b870d40d486 --- /dev/null +++ b/test/sophia/conflict.result @@ -0,0 +1,7 @@ +dofile('conflict.lua') +--- +... +test_conflict() +--- +- 1 +... diff --git a/test/sophia/conflict.test.lua b/test/sophia/conflict.test.lua new file mode 100644 index 0000000000000000000000000000000000000000..d83c03a7a5e8144f2a70ad40c66e847253cee311 --- /dev/null +++ b/test/sophia/conflict.test.lua @@ -0,0 +1,4 @@ + +dofile('conflict.lua') + +test_conflict() diff --git a/test/sophia/suite.ini b/test/sophia/suite.ini index 6c365fdcfe8559fb0a1a132314e087e898a24652..4a727bc00c8c579955bb592dfb947d62314b6c7e 100644 --- a/test/sophia/suite.ini +++ b/test/sophia/suite.ini @@ -5,5 +5,5 @@ script = box.lua disabled = info.test.lua truncate.test.lua random.test.lua valgrind_disabled = release_disabled = -lua_libs = suite.lua index_random_test.lua +lua_libs = suite.lua index_random_test.lua conflict.lua use_unix_sockets = True diff --git a/third_party/sophia b/third_party/sophia index ee2f6d01454a2374877bcdda5b5791497b737f9b..c67e03f12a7ceb646c7985c933385658d8c58ad9 160000 --- a/third_party/sophia +++ b/third_party/sophia @@ -1 +1 @@ -Subproject commit ee2f6d01454a2374877bcdda5b5791497b737f9b +Subproject commit c67e03f12a7ceb646c7985c933385658d8c58ad9