From 292cd479ba29cb9e28f1972f1917715291a1815e Mon Sep 17 00:00:00 2001 From: Ilya <markovilya197@gmail.com> Date: Fri, 16 Jun 2017 18:21:57 +0300 Subject: [PATCH] Add a wrapper for box.begin/box.commit call Add box.atomic(fun, arg) wrapper to execute fun(arg) in a transaction. Closes #818 --- src/box/lua/schema.lua | 15 +++++++ test/box/misc.result | 3 +- test/box/transaction.result | 80 +++++++++++++++++++++++++++++++++++ test/box/transaction.test.lua | 42 ++++++++++++++++++ 4 files changed, 139 insertions(+), 1 deletion(-) diff --git a/src/box/lua/schema.lua b/src/box/lua/schema.lua index 0041286b63..88c912f6cc 100644 --- a/src/box/lua/schema.lua +++ b/src/box/lua/schema.lua @@ -228,6 +228,21 @@ box.begin = function() box.error() end end + +local function atomic_tail(status, ...) + if not status then + box.rollback() + error((...), 2) + end + box.commit() + return ... +end + +box.atomic = function(fun, ...) + box.begin() + return atomic_tail(pcall(fun, ...)) +end + -- box.commit yields, so it's defined as Lua/C binding -- box.rollback yields as well diff --git a/test/box/misc.result b/test/box/misc.result index e8ff143619..cf56fd4750 100644 --- a/test/box/misc.result +++ b/test/box/misc.result @@ -55,7 +55,8 @@ t = {} for n in pairs(box) do table.insert(t, tostring(n)) end table.sort(t) ... t --- -- - backup +- - atomic + - backup - begin - cfg - commit diff --git a/test/box/transaction.result b/test/box/transaction.result index 9c24d1f7b2..746f7e12c2 100644 --- a/test/box/transaction.result +++ b/test/box/transaction.result @@ -423,3 +423,83 @@ function gh_1638() box.begin(); box.rollback() end for i = 1, 1000 do fiber.create(function() gh_1638() end) end --- ... +-- +--gh-818 add atomic() +-- +space = box.schema.space.create('atomic') +--- +... +index = space:create_index('primary') +--- +... +test_run:cmd("setopt delimiter ';'") +--- +- true +... +function args(...) + return 'args', ... +end; +--- +... +box.atomic(args, 1, 2, 3, 4, 5); +--- +- args +- 1 +- 2 +- 3 +- 4 +- 5 +... +function tx() + space:auto_increment{'first row'} + space:auto_increment{'second row'} + return space:select{} +end; +--- +... +box.atomic(tx); +--- +- - [1, 'first row'] + - [2, 'second row'] +... +function tx_error(space) + space:auto_increment{'third'} + space:auto_increment{'fourth'} + error("some error") +end; +--- +... +box.atomic(tx_error, space); +--- +- error: '[string "function tx_error(space) space:auto_incre..."]:1: some error' +... +function nested(space) + box.begin() +end; +--- +... +box.atomic(nested, space); +--- +- error: 'Operation is not permitted when there is an active transaction ' +... +function rollback(space) + space:auto_increment{'fifth'} + box.rollback() +end; +--- +... +box.atomic(rollback, space); +--- +... +test_run:cmd("setopt delimiter ''"); +--- +- true +... +space:select{} +--- +- - [1, 'first row'] + - [2, 'second row'] +... +space:drop() +--- +... diff --git a/test/box/transaction.test.lua b/test/box/transaction.test.lua index 22e6e6cca9..cda0eb151a 100644 --- a/test/box/transaction.test.lua +++ b/test/box/transaction.test.lua @@ -195,3 +195,45 @@ box.space.test:drop() -- function gh_1638() box.begin(); box.rollback() end for i = 1, 1000 do fiber.create(function() gh_1638() end) end + +-- +--gh-818 add atomic() +-- +space = box.schema.space.create('atomic') +index = space:create_index('primary') +test_run:cmd("setopt delimiter ';'") + +function args(...) + return 'args', ... +end; +box.atomic(args, 1, 2, 3, 4, 5); + +function tx() + space:auto_increment{'first row'} + space:auto_increment{'second row'} + return space:select{} +end; +box.atomic(tx); + +function tx_error(space) + space:auto_increment{'third'} + space:auto_increment{'fourth'} + error("some error") +end; +box.atomic(tx_error, space); + +function nested(space) + box.begin() +end; +box.atomic(nested, space); + +function rollback(space) + space:auto_increment{'fifth'} + box.rollback() +end; +box.atomic(rollback, space); + +test_run:cmd("setopt delimiter ''"); +space:select{} + +space:drop() -- GitLab