Версия:

Управление экземплярами

Управление экземплярами

Общие сведения

For general information and examples, see section Transaction control.

Observe the following rules when working with transactions:

Rule #1

The requests in a transaction must be sent to a server as a single block. It is not enough to enclose them between begin and commit or rollback. To ensure they are sent as a single block: put them in a function, or put them all on one line, or use a delimiter so that multi-line requests are handled together.

Rule #2

All database operations in a transaction should use the same storage engine. It is not safe to access tuple sets that are defined with {engine='vinyl'} and also access tuple sets that are defined with {engine='memtx'}, in the same transaction.

Rule #3

Requests which cause changes to the data definition – create, alter, drop, truncate – must not be used.

Индекс

Ниже приведен перечень всех функций для управления транзакциями.

Имя Использование
box.begin() Начало транзакции.
box.commit() End the transaction and save all changes
box.rollback() End the transaction and discard all changes
box.savepoint() Get a savepoint descriptor
box.rollback_to_savepoint() Do not end the transaction and discard all changes made after a savepoint
box.atomic() Execute a function, treating it as a transaction
box.on_commit() Define a trigger that will be activated by box.commit
box.on_rollback() Define a trigger that will be activated by box.rollback
is_in_txn() State whether a transaction is in progress
box.begin()

Начните транзакцию. Отключите неявную передачу данных до окончания транзакции. Сигнал о записи в :ref :журнал упреждающей записи <internals-wal> будет задержан до окончания транзакции. Фактически файбер, который выполняет функцию box.begin(), начинает «активную транзакцию со множеством запросов» с блокировкой всех остальных файберов.

Возврат:error if this operation is not permitted because there is already an active transaction.
Возврат:error if for some reason memory cannot be allocated.
box.commit()

End the transaction, and make all its data-change operations permanent.

Возврат:error and abort the transaction in case of a conflict.
Возврат:error if the operation fails to write to disk.
Возврат:error if for some reason memory cannot be allocated.
box.rollback()

End the transaction, but cancel all its data-change operations. An explicit call to functions outside box.space that always yield, such as fiber.sleep() or fiber.yield(), will have the same effect.

box.savepoint()

Return a descriptor of a savepoint (type = table), which can be used later by box.rollback_to_savepoint(savepoint). Savepoints can only be created while a transaction is active, and they are destroyed when a transaction ends.

Возврат:savepoint table
Rtype:Lua object
Возврат:error if the savepoint cannot be set in absence of active transaction.
Возврат:error if for some reason memory cannot be allocated.
box.rollback_to_savepoint(savepoint)

Do not end the transaction, but cancel all its data-change and box.savepoint() operations that were done after the specified savepoint.

Возврат:error if the savepoint cannot be set in absence of active transaction.
Возврат:error if the savepoint does not exist.

Пример:

function f()
  box.begin()           -- start transaction
  box.space.t:insert{1} -- this will not be rolled back
  local s = box.savepoint()
  box.space.t:insert{2} -- this will be rolled back
  box.rollback_to_savepoint(s)
  box.commit()          -- end transaction
end
box.atomic(function-name[, function-arguments])

Execute a function, acting as if the function starts with an implicit box.begin() and ends with an implicit box.commit() if successful, or ends with an implicit box.rollback() if there is an error.

Возврат:the result of the function passed to atomic() as an argument.
Возврат:any error that box.begin() and box.commit() can return.
box.on_commit(trigger-function[, old-trigger-function])

Define a trigger for execution when a transaction ends due to an event such as box.commit.

The trigger function may take an iterator parameter, as described in an example for this section.

The trigger function should not access any database spaces.

If the trigger execution fails and raises an error, the effect is severe and should be avoided – use Lua’s pcall() mechanism around code that might fail.

box.on_commit() must be invoked within a transaction, and the trigger ceases to exist when the transaction ends.

Параметры:
  • trigger-function (function) – function which will become the trigger function
  • old-trigger-function (function) – existing trigger function which will be replaced by trigger-function
Возврат:

nil or function pointer

If the parameters are (nil, old-trigger-function), then the old trigger is deleted.

Подробная информация о характеристиках триггера находится в разделе Триггеры.

Simple and useless example: this will display „commit happened“:

function f()
function f() print('commit happened') end
box.begin() box.on_commit(f) box.commit()

But of course there is more to it: the function parameter can be an ITERATOR.

The iterator goes through the effects of every request that changed a space during the transaction.

The iterator will have:

  • an ordinal request number,
  • the old value of the tuple before the request (this will be nil for an insert request),
  • the new value of the tuple after the request (this will be nil for a delete request),
  • and the id of the space.

Less simple more useful example: this will display the effects of two replace requests:

box.space.test:drop()
s = box.schema.space.create('test')
i = box.space.test:create_index('i')
function f(iterator)
  for request_number, old_tuple, new_tuple, space_id in iterator() do
    print('request_number ' .. tostring(request_number))
    print('  old_tuple ' .. tostring(old_tuple[1]) .. ' ' .. old_tuple[2])
    print('  new_tuple ' .. tostring(new_tuple[1]) .. ' ' .. new_tuple[2])
    print('  space_id ' .. tostring(space_id))
  end
end
s:insert{1,'-'}
box.begin() s:replace{1,'x'} s:replace{1,'y'} box.on_commit(f) box.commit()

The result will look like this:

tarantool> box.begin() s:replace{1,'x'} s:replace{1,'y'} box.on_commit(f) box.commit()
request_number 1
  old_tuple 1 -
  new_tuple 1 x
  space_id 517
request_number 2
  old_tuple 1 x
  new_tuple 1 y
  space_id 517
box.on_rollback(trigger-function[, old-trigger-function])

Define a trigger for execution when a transaction ends due to an event such as box.rollback.

The parameters and warnings are exactly the same as for box.on-commit.

box.is_in_txn()

If a transaction is in progress (for example the user has called box.begin and has not yet called either box.commit or box.rollback, return true. Otherwise return false.