Skip to content

Add iproto requests for stream transactions #2918

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Jun 7, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 106 additions & 12 deletions doc/dev_guide/internals/box_protocol.rst
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,8 @@ The IPROTO constants that appear within requests or responses that we will descr
IPROTO_RAFT_VCLOCK=0x03
IPROTO_VERSION=0x54
IPROTO_FEATURES=0x55
IPROTO_TIMEOUT=0x56
IPROTO_TXN_ISOLATION = 0x59


To denote message descriptions we will say ``msgpack(...)`` and within it we will use modified
Expand Down Expand Up @@ -706,6 +708,96 @@ IPROTO_SQL_TEXT (0x40) and statement-text (string) if executing an SQL string.
Thus the IPROTO_PREPARE map item is the same as the first item of the
:ref:`IPROTO_EXECUTE <box_protocol-execute>` body.

.. _box_protocol-begin:

IPROTO_BEGIN = 0x0e
~~~~~~~~~~~~~~~~~~~~~

Begin a transaction in the specified stream.
See :ref:`stream:begin() <net_box-stream_begin>`.
The body is optional and can contain two items:

.. cssclass:: highlight
.. parsed-literal::

# <size>
msgpack(:samp:`{{MP_UINT unsigned integer = size(<header>) + size(<body>)}}`)
# <header>
msgpack({
IPROTO_REQUEST_TYPE: IPROTO_BEGIN,
IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`,
IPROTO_STREAM_ID: :samp:`{{MP_UINT unsigned integer}}`
})
# <body>
msgpack({
IPROTO_TIMEOUT: :samp:`{{MP_DOUBLE}}`,
IPROTO_TXN_ISOLATION: :samp:`{{MP_UINT unsigned integer}}`
})

IPROTO_TIMEOUT is an optional timeout (in seconds). After it expires,
the transaction will be rolled back automatically.

.. // TODO: add link to transaction isolation docs once they're ready
IPROTO_TXN_ISOLATION is the transaction isolation level. It can take
the following values:

.. // TODO: provide links to level descriptions
- ``TXN_ISOLATION_DEFAULT = 0`` -- use the global default level (default value)
- ``TXN_ISOLATION_READ_COMMITTED = 1`` -- read changes that are committed but not confirmed yet
- ``TXN_ISOLATION_READ_CONFIRMED = 2`` -- read confirmed changes
- ``TXN_ISOLATION_BEST_EFFORT = 3`` -- determine isolation level automatically
Comment on lines +745 to +748
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- ``TXN_ISOLATION_DEFAULT = 0`` -- use the global default level (default value)
- ``TXN_ISOLATION_READ_COMMITTED = 1`` -- read changes that are committed but not confirmed yet
- ``TXN_ISOLATION_READ_CONFIRMED = 2`` -- read confirmed changes
- ``TXN_ISOLATION_BEST_EFFORT = 3`` -- determine isolation level automatically
- ``TXN_ISOLATION_DEFAULT = 0`` -- use the global default level (default value).
- ``TXN_ISOLATION_READ_COMMITTED = 1`` -- read changes that are committed but not confirmed yet.
- ``TXN_ISOLATION_READ_CONFIRMED = 2`` -- read confirmed changes.
- ``TXN_ISOLATION_BEST_EFFORT = 3`` -- determine isolation level automatically.

You can find the list punctuation rules in our style guide.


See :ref:`Binary protocol -- streams <box_protocol-streams>` to learn more about
stream transactions in the binary protocol.


.. _box_protocol-commit:

IPROTO_COMMIT = 0x0f
~~~~~~~~~~~~~~~~~~~~~

Commit the transaction in the specified stream.
See :ref:`stream:commit() <net_box-stream_commit>`.

.. cssclass:: highlight
.. parsed-literal::

# <size>
msgpack(7)
# <header>
msgpack({
IPROTO_REQUEST_TYPE: IPROTO_COMMIT,
IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`,
IPROTO_STREAM_ID: :samp:`{{MP_UINT unsigned integer}}`
})

See :ref:`Binary protocol -- streams <box_protocol-streams>` to learn more about
stream transactions in the binary protocol.


.. _box_protocol-rollback:

IPROTO_ROLLBACK = 0x10
~~~~~~~~~~~~~~~~~~~~~

Rollback the transaction in the specified stream.
See :ref:`stream:rollback() <net_box-stream_rollback>`.

.. cssclass:: highlight
.. parsed-literal::

# <size>
msgpack(7)
# <header>
msgpack({
IPROTO_REQUEST_TYPE: IPROTO_ROLLBACK,
IPROTO_SYNC: :samp:`{{MP_UINT unsigned integer}}`,
IPROTO_STREAM_ID: :samp:`{{MP_UINT unsigned integer}}`
})

See :ref:`Binary protocol -- streams <box_protocol-streams>` to learn more about
stream transactions in the binary protocol.


.. _box_protocol-ping:

Expand Down Expand Up @@ -746,9 +838,9 @@ Tarantool nodes in :ref:`synchronous replication <repl_sync>`.
The messages are not supposed to be used by any client applications in their
regular connections.

.. _box_protocol-confirm:
.. _box_protocol-raft_confirm:

IPROTO_CONFIRM = 0x28
IPROTO_RAFT_CONFIRM = 0x28
~~~~~~~~~~~~~~~~~~~~~

This message confirms that the transactions originated from the instance
Expand All @@ -775,9 +867,9 @@ The body is a 2-item map:
})


.. _box_protocol-rollback:
.. _box_protocol-raft_rollback:

IPROTO_ROLLBACK = 0x29
IPROTO_RAFT_ROLLBACK = 0x29
~~~~~~~~~~~~~~~~~~~~~~

This message says that the transactions originated from the instance
Expand Down Expand Up @@ -1281,16 +1373,18 @@ each call to conn:new_stream() assigns a new number, starting with 1.
.. _box_protocol-stream_transactions:

The client makes stream transactions by sending, in order:
IPROTO_BEGIN, the transaction data-change and query requests,
IPROTO_COMMIT or IPROTO_ROLLBACK.
Each request must contain the same IPROTO_STREAM_ID value.
With streaming there is no need to add
:ref:`IPROTO_FLAGS <box_protocol-flags>` and IPROTO_FLAG_COMMIT
in the header of the last request of a transaction.
Rollback will be automatic if disconnect occurs before commit is possible.

1. IPROTO_BEGIN with an optional transaction timeout in the IPROTO_TIMEOUT field of the request body.
2. The transaction data-change and query requests.
3. IPROTO_COMMIT or IPROTO_ROLLBACK.

All these requests must contain the same IPROTO_STREAM_ID value.

A rollback will happen automatically if
a disconnect occurs or the transaction timeout expires before the commit is possible.

Thus there are now multiple ways to do transactions:
with net_box and stream:begin() and stream:commit() or stream:rollback()
with ``net_box`` ``stream:begin()`` and ``stream:commit()`` or ``stream:rollback()``
which cause IPROTO_BEGIN and IPROTO_COMMIT or IPROTO_ROLLBACK with
the current value of stream.stream_id;
with :ref:`box.begin() <box-begin>` and :ref:`box.commit() <box-commit>` or :ref:`box.rollback() <box-rollback>`;
Expand Down