The REST Client API provides transaction control through the /transactions
service and a txid
parameter available on document manipulation and search requests. This section covers the following topics:
Many of the services available through the REST Client API allow you to perform an operation in the context of a specific transaction by passing a transaction id in a txid
parameter. The /transactions
service supports the creation and administration of these transactions.
The /transactions
service supports the following operations:
Operation | Method | Description | More Information |
---|---|---|---|
Create | POST | Create a multi-statement transaction. See Creating a Transaction. | Creating a Transaction |
The /transactions/{txid}
service supports the following operations:
Operation | Method | Description | More Information |
---|---|---|---|
Commit or Rollblack | POST | Commit or rollback an open transaction. | Committing or Rolling Back a Transaction |
Status | GET | Retrieve transaction status in XML or JSON. | Checking Transaction Status |
This section gives a brief introduction to the MarkLogic Server transaction model as it applies to the REST Client API. For a full discussion of the transaction model, see Understanding Transactions in MarkLogic Server in the Application Developer's Guide..
By default, each request to a REST Client API service is equivalent to a single statement transaction. That is, the request is evaluated as single transaction.
For example, when you update a document in the database by making a PUT request to the /documents
service, the service effectively creates a new transaction, updates the document, commits the transaction, and then sends back a response. The update is immediately visible in the database and available to other requests.
The REST Client API also allows your application to take direct control of transaction boundaries so that multiple request are evaluated in the same transaction context. This is equivalent to the multi-statement transactions described in Multi-Statement Transaction Concept Summary in the Application Developer's Guide.
Using multi-statement transactions, you can make several update requests and commit them as a single transaction, ensuring either all or none of the updates appear in the database. The document manipulation and search capabilities of the REST Client API support multi-statement transactions.
To use multi-statement transactions:
/transactions
service. The service returns a transaction id. See Creating a Transaction.txid
request parameter. See Associating a Transaction with a Request./transactions
service. See Committing or Rolling Back a Transaction.If your application interacts with MarkLogic Server through a load balancer, you might need to include a load balancer session cookie in your requests to preserve session affinity. For details, see Managing Transactions When Using a Load Balancer.
When you explicitly create a transaction, you must explicitly commit or roll it back. Failure to do so leaves the transaction open until the request or transaction timeout expires. Open transactions can hold locks and consume system resources.
If the request or transaction timeout expires before a transaction is committed, the transaction is automatically rolled back and all updates are discarded. Configure the request timeout of the App Server using the Admin UI. Configure the timeout of a single transaction by setting the timeLimit
request parameter during transaction creation.
Note that if you're using multi-statement transactions, you must create, use, and commit (or rollback) on the transaction using the same database. You cannot create a transaction on one database and then attempt to perform an operation such as read, write, or search using the transaction id and a different database.
To create a transaction, send a POST request to the /transactions
service with a URL of the form:
http://host:port/version/transactions
The service responds with a transaction id in the Location
response header. Use the transaction id to control the transaction in which MarkLogic Server evaluates future requests; see Associating a Transaction with a Request.
The transaction id returned in the Location header is of the form. You can use this resource path to subsequently commit or rollback the transaction, as described in Committing or Rolling Back a Transaction.
/version/transactions/txnid
# Windows users, see Modifying the Example Commands for Windows $ curl -X POST -d "" --anyauth --user user:password \ -H "Content-type: text/plain" \ http://localhost:8000/LATEST/transactions ... HTTP/1.1 303 See Created Transaction Location: /v1/transactions/3148548124558550433
When supplying the transaction id to future requests, use only the txnid
portion. For example:
$ curl -X PUT -T ./example.xml --anyauth --user user:password \ 'http://localhost:8000/LATEST/documents?uri=/xml/example.xml&txid=3148548124558550433'
Transactions created using the /transactions
service must be explicitly committed or rolled back. Failure to commit or rollback the transaction before the request timeout expires causes an automatic rollback. You can assign a shorter time limit to a transaction using the timeLimit URL parameter:
http://host:port/version/transactions?timeLimit=seconds
As a convenience for identifying a transaction in server status reports, you can assign a name to the transaction. The default transaction name is client-txn. To assign a transaction, add the name
URL parameter to your request:
http://host:port/version/transactions?name=txn_name
Once you create a transaction, as described in Creating a Transaction, you can evaluate document manipulation and search requests in that transaction by supplying the transaction id wherever a txid
URL parameter is supported.
For example, to perform a document update in the context of a specific transaction, include the transaction id in a PUT request to the /documents
service:
# Windows users, see Modifying the Example Commands for Windows $ curl -X PUT -T ./example.xml --anyauth --user user:password \ 'http://localhost:8000/LATEST/documents?uri=/xml/example.xml&txid=3148548124558550433'
Updates associated with an explicit transaction are visible to other requests executed within the same transaction, but they are not visible outside the transaction until the transaction is committed. See Committing or Rolling Back a Transaction.
The database context in which you evaluate the request must be the same as the database context in which the transaction was created.
To commit a transaction created by making a POST request to the /transactions
service, send a POST request to the /transactions/{txid}
service with a URL of the form:
http://host:port
/version/transactions/txid?result=outcome
Where txid is a transaction id returned in the Location
header of the transaction creation request response, and outcome is either commit
or rollback
.
MarkLogic Server responds with a 204 when a transaction is successfully committed or rolled back, or if the transaction no longer exists.
Transactions created using the /transactions
service should be explicitly commited or rolled back. Failure to commit or rollback the transaction before the request timeout expires causes an automatic rollback. Leaving transactions open unnecessarily potentially holds locks on documents and consume system resources.
To query the status of a transaction, send a GET request to the /transactions
service with a URL of the form:
http://host:port
/version/transactions/txid
Where txid
is a transaction id returned in the Location
header of the transaction creation request response.
MarkLogic Server responds with transaction status information in XML or JSON, depending upon the format requested through the HTTP Accept
header or the format
URL parameter
. The default format is XML. If both the Accept
header and the format
parameter are set, the format parameter takes precedence.
To request a specific format, set the Accept
header to application/json
or application/xml
, or set the format
URL parameter to xml
or json
. The following example requests JSON output using the Accept
header:
# Windows users, see Modifying the Example Commands for Windows $ curl -X GET --anyauth --user user:password \ -H "Accept: application/json" \ http://localhost:8000/LATEST/transactions/216104635458437451
The XML status information returned in the response takes the following form:
<rapi:transaction-status xmlns:rapi="http://marklogic.com/rest-api"> <rapi:host> <rapi:host-id>1506593501555860493</rapi:host-id> <rapi:host-name>somehost</rapi:host-name> </rapi:host> <rapi:server> <rapi:server-id>17994162681305741146</rapi:server-id> <rapi:server-name>App-Services</rapi:server-name> </rapi:server> <rapi:database> <rapi:database-id>8896678293064963766</rapi:database-id> <rapi:database-name>Documents</rapi:database-name> </rapi:database> <rapi:transaction-id>216104635458437451</rapi:transaction-id> <rapi:transaction-name>client-txn</rapi:transaction-name> <rapi:transaction-mode>update</rapi:transaction-mode> <rapi:transaction-timestamp>0</rapi:transaction-timestamp> <rapi:transaction-state>idle</rapi:transaction-state> <rapi:canceled>false</rapi:canceled> <rapi:start-time>2012-08-18T17:23:00-07:00</rapi:start-time> <rapi:time-limit>600</rapi:time-limit> <rapi:max-time-limit>3600</rapi:max-time-limit> <rapi:user>7071164303237443533</rapi:user> <rapi:admin>true</rapi:admin> </rapi:transaction-status>
The JSON status information returned in the response takes the following form:
{ "rapi:transaction-status": { "rapi:host": { "rapi:host-id": "1506593501555860493", "rapi:host-name": "somehost" }, "rapi:server": { "rapi:server-id": "17994162681305741146", "rapi:server-name": "App-Services" }, "rapi:database": { "rapi:database-id": "8896678293064963766", "rapi:database-name": "Documents" }, "rapi:transaction-id": "216104635458437451", "rapi:transaction-name": "client-txn", "rapi:transaction-mode": "update", "rapi:transaction-timestamp": "0", "rapi:transaction-state": "idle", "rapi:canceled": "false", "rapi:start-time": "2012-08-18T17:23:00-07:00", "rapi:time-limit": "600", "rapi:max-time-limit": "3600", "rapi:user": "7071164303237443533", "rapi:admin": "true" } }
You can also check transaction status using the Admin Interface or xdmp:host-status.
This section applies only to client applications that use multi-statement (multi-request) transactions and interact with a MarkLogic Server cluster through a load balancer. Requests that include a transaction id (txid
) request parameter are part of a multi-statement transaction.
When you use a load balancer, it is possible for requests from your application to MarkLogic Server to be routed to different hosts, even within the same session. This has no effect on most interactions with MarkLogic Server, but all requests that are part of the same multi-statement transaction must be routed to the same host within your MarkLogic cluster. This consistent routing through a load balancer is called session affinity.
Most load balancers provide a mechanism that supports session affinity. This usually takes the form of a session cookie that originates on the load balancer. The client acquires the cookie from the load balancer, and passes it on any requests that belong to the session. You can use a load balancer session cookie to preserve session affinity across requests in the same transaction. The exact steps required to configure a load balancer to generate session cookies depends on the load balancer. Consult your load balancer documentation for details.
The following steps describe to use load balancer cookies to preserve session affinity across requests in the same transaction. A graphical representation of this process follows.
/transactions
service. The load balancer directs the request to some host in your MarkLogic cluster. /transactions/{txid}
service that includes the transaction id (in the URL) and session cookie. The following diagram illustrates the steps described above. The steps in the diagram correspond to the steps in the procedure. The transaction id is represented in the diagram by tid.
The load balancer attaches a session cookie to responses to all REST Client API requests, but your application is only required to pass it back as part of a multi-statement transaction operation.
A REST Client API application can use a session cookie beyond the boundaries of a single multi-statement transaction by attaching the session cookie to other requests. However, most operations do not require session affinity. Omitting the session cookie from requests that are not part of a multi-statement transaction enables the load balancer to distribute work across your MarkLogic cluster more effectively.
You can have multiple multi-statement transactions open concurrently, and you can intermix single-statement transaction requests and multi-statement transaction requests, as long as you preserve the correct association between a transaction id and its session cookie in the multi-statement transaction requests.
You must not send a request that includes a transaction id for one transaction with a session cookie associated with a different one. Some HTTP connection pooling implementations may not properly handle session cookies. For example, a pooled connection might return a cookie that is not the correct one for the transaction you are trying to use.