Transactions
Stay consistent!
Enforce Atomicity, Consistency, Isolation and Durability with multi-document transactions.
Introduction
An operation on a single document is atomic. This is enough in most use cases since embedded documents can capture relationships between data in a single document.
However, for situations that require atomicity for multiple write requests or consistency between multiple read requests, multi-document transactions must be used.
Multi-document transaction requires at least MongoDB v4.0 configured as a Replica Set.
The demo application shown during the talk is available from github at restheart-txn-demo
Sessions
MongoDB v3.6 introduced sessions, defined as follows:
A session is an abstract concept that represents a set of sequential operations executed by an application that are related in some way.
Sessions allows to enforce casual consistency and are the foundation for transactions.
Sessions are available also in the OS version of RESTHeart. RESTHeart adds support for multi-document transactions on top of sessions.
Start a session
POST /_sessions HTTP/1.1
{ "causallyConsistent": true }
HTTP/1.1 201 Created
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: Location, ETag, X-Powered-By
Connection: keep-alive
Content-Length: 0
Content-Type: application/json
Date: Wed, 19 Jun 2019 09:01:04 GMT
Location: http://localhost:8009/_sessions/11c3ceb6-7b97-4f34-ba3f-689ea22ce6e0
X-Powered-By: restheart.org
The causallyConsistent property is optional, true by default.
The session id is returned via the Location response header. In this case
sid=11c3ceb6-7b97-4f34-ba3f-689ea22ce6e0
Execute a request in a session
Requests can be executed in a session using the | sid query parameter. |
POST /coll?sid=11c3ceb6-7b97-4f34-ba3f-689ea22ce6e0 HTTP/1.1
{"foo": "bar"}
HTTP/1.1 201 Created
GET /coll?sid=11c3ceb6-7b97-4f34-ba3f-689ea22ce6e0 HTTP/1.1
HTTP/1.1 200 OK
Transactions
Transactions are handled in sessions; per each session, one transaction at a time can be started.
Transaction Status
The following tables lists all possible transactions status.
status | description |
IN | The transaction is in progress |
ABORTED | The transaction has been aborted, either explicitly or due to an error or because it expired |
COMMITTED | The transaction has been successfully committed |
Error handling
The client is responsible of handling the following errors when executing requests inside a transaction and incorporate retry logic.
The following table shows the most important error status that should be handled.
error | response status | description |
---|---|---|
The given transaction is not in-progress | 406 | A request is executed in a transaction whose status is not IN |
Write conflict inside transaction | 409 | This error occurs when a transaction updating one of more documents tries to commit after a second transaction have been successfully committed updating the same data. |
By default, a transaction must have a runtime of less than one minute. After that, the transaction is automatically ABORTED. Check MongoDB Documentation for more information.
Start the transaction
Transaction are started in sessions.
The following POST request starts the transaction in session 11c3ceb6-7b97-4f34-ba3f-689ea22ce6e0
POST /_sessions/11c3ceb6-7b97-4f34-ba3f-689ea22ce6e0/_txns HTTP/1.1
HTTP/1.1 201 Created
Location: http://localhost:8009/_sessions/11c3ceb6-7b97-4f34-ba3f-689ea22ce6e0/_txns/1
...
Note that the Location
response header returns the id of the transaction or txn
. In this case:
txn=1
Get the current transaction status
GET /_sessions/11c3ceb6-7b97-4f34-ba3f-689ea22ce6e0/_txns HTTP/1.1
HTTP/1.1 200 Ok
...
{
"currentTxn": {
"id": 1,
"status": "IN"
}
}
Execute requests in the transaction
Requests can be executed in the transaction using the sid
and txn
query parameters.
POST /coll?sid=11c3ceb6-7b97-4f34-ba3f-689ea22ce6e0&txn=1 HTTP/1.1
{"foo": "bar"}
HTTP/1.1 201 Created
GET /coll?sid=11c3ceb6-7b97-4f34-ba3f-689ea22ce6e0&txn=1 HTTP/1.1
HTTP/1.1 200 Ok
Commit the transaction
Use the method PATCH to commit the transaction.
PATCH /_sessions/11c3ceb6-7b97-4f34-ba3f-689ea22ce6e0/_txns/1 HTTP/1.1
HTTP/1.1 200 OK
Abort the transaction
Use the method DELETE to abort the transaction.
DELETE /_sessions/11c3ceb6-7b97-4f34-ba3f-689ea22ce6e0/_txns/1 HTTP/1.1
HTTP/1.1 204 No Content