Not that long ago, directory servers didn’t really offer that much in the way of being able to perform atomic operations. The LDAP specification requires that individual updates be atomic, so you could be sure that if you updated multiple attributes in the same entry with a single modify operation then they would all succeed or all fail. In some directory servers, that’s the only type of atomicity you can get.
When the LDAPv3 specifications were updated a few years ago, some new RFCs were published that make it possible to perform some basic atomic operations within a single entry. They include:
- LDAP Modify-Increment Extension (RFC 4525) — This makes it possible to atomically increment or decrement a single-valued integer attribute by a specified amount without needing to know the current value.
- LDAP Read Entry Controls (RFC 4527) — This makes it possible to retrieve an entry immediately before a delete, modify, or modify DN operation, or immediately after an add, modify, or modify DN operation.
- LDAP Assertion Control (RFC 4528) — This makes it possible to request that an operation be processed only if the target entry matches a specified filter.
These features can be very helpful when dealing with a single entry because they provide an atomic compare-and-set type of functionality. However, they do not provide any support for interacting with multiple entries as a single atomic unit. For that, you need transactions, and the UnboundID Directory Server supports two kinds of transactions.
The first type of transaction offered by the UnboundID Directory Server is called “batched transactions”, because it allows you to provide a number of add, delete, modify, modify DN, or password modify operations (targeting the same entry or different entries) which will get batched up and processed as a single atomic unit. This capability is based on the draft-zeilenga-ldap-txn Internet Draft titled “LDAP Transactions”, and the process for using them is basically as follows:
- Send a start transaction extended request to the Directory Server. In its response, the server will provide a transaction ID.
- Send a set of add, delete, modify, modify DN, and/or password modify operations. In each request, include a control that includes the transaction ID that you got in the start transaction response so that the server knows that operation is part of the transaction.
- Send an end transaction extended request to the Directory Server indicating that the transaction should be committed. The server will process all of the operations as a single atomic unit so that they will either all succeed or will all fail.
This can be very useful, but you are limited to only performing write operations, so you can’t read an entry and then attempt to update it with the guarantee that it hasn’t been modified between the read and the write. We do provide support for using the increment, read entry, and assertions capabilities with batched transactions, so you can read an entry outside of the transaction and then use the LDAP assertion control in an attempt to ensure that it hasn’t been altered since you last read it, but if something did happen to modify the entry then the entire transaction would fail.
The second type of transactions offered by the UnboundID Directory Server is called “interactive transactions”, because operations which are part of the transaction are processed immediately as they are requested rather than being batched up and processed all at once. They provide all of the capabilities offered by batched transactions, but also make it possible to include search and compare operations within the transaction.
With interactive transactions, it is possible to read an entry and then modify it based on what you read with the guarantee that no other client would be allowed to change it while the transaction is still in progress. Once an entry has been read (via a search or compare operation) as part of a transaction, then any attempt to alter it outside of that transaction will be forced to wait until the transaction has been committed or aborted, although attempts to read it will still be allowed. Once an entry has been altered as part of a transaction (via an add, delete, modify, modify DN, or password modify operation), then any attempt to access it from outside the transaction will be forced to wait until the transaction has been committed or aborted. That is, any changes made as part of an interactive transaction will only be visible within the context of that transaction until it has been committed.
Using Transactions in Client Code
At present, the implementations for both batched transactions and interactive transactions are specific to the UnboundID Directory Server.
The “LDAP Transactions” Internet Draft hasn’t yet reached a sufficient level of maturity to allow interoperable implementations to be created (in particular, it doesn’t specify what OIDs should be used for the control, extended requests, and extended responses), nor is there a guarantee that this draft won’t change in incompatible ways before it is finalized and published as an RFC (if that ever happens). As a result, we guarantee that our implementation of batched transactions will remain backwards compatible, but we can’t make any claims of interoperability with any other type of client or server. If the “LDAP Transactions” draft ever is published as an RFC, then we will support the final specification in addition to what we currently offer.
The interactive transactions capability that we offer is specific to the UnboundID Directory Server and is not based on any public specification, since no draft or RFC covers anything like it.
When interacting with our Directory Server, the UnboundID LDAP SDK for Java may be used to perform both batched and interactive transactions. The version of the LDAP SDK which is available for public download doesn’t offer this capability, but if you get our Directory Server, then you also get a special “Commercial Edition” version of the LDAP SDK for Java that contains additional features that make it possible to use additional functionality specific to our Directory Server. This includes support for batched and interactive transactions, as well as other custom controls and extended operations we have added to our server, and also includes APIs for interacting with monitoring information and administrative tasks. The only differences between the Standard Edition and Commercial Edition versions of our LDAP SDK are around features that are specific to our Directory Server, so there really isn’t any benefit to having the Commercial Edition of our LDAP SDK if you don’t also have our Directory Server.
As with batched transactions, if that capability is ever published as an RFC, then the Standard Edition of our LDAP SDK (which may be used with any LDAPv3 directory server) will be updated to support that specification.