Understanding session management with the driver in Amazon QLDB - Amazon Quantum Ledger Database (Amazon QLDB)

Understanding session management with the driver in Amazon QLDB

If you have experience using a relational database management system (RDBMS), you might be familiar with concurrent connections. QLDB doesn't have the same concept of a traditional RDBMS connection because transactions are run with HTTP request and response messages.

In QLDB, the analogous concept is an active session. A session is conceptually similar to a user login—it manages information about your data transaction requests to a ledger. An active session is one that is actively running a transaction. It can also be a session that recently finished a transaction where the service anticipates it will start another transaction immediately. QLDB supports one actively running transaction per session.

The limit of concurrent active sessions per ledger is defined in Quotas and limits in Amazon QLDB. After this limit is reached, any session that tries to start a transaction will result in an error (LimitExceededException).

For best practices for configuring a session pool in your application using the QLDB driver, see Configuring the QldbDriver object in Amazon QLDB driver recommendations.

Session lifecycle

The following sequence of QLDB Session API operations represents the typical lifecycle of a QLDB session:

  1. StartSession

  2. StartTransaction

  3. ExecuteStatement

  4. CommitTransaction

  5. Repeat steps 2–4 to start more transactions (one transaction at a time).

  6. EndSession

Session expiration

QLDB expires and discards a session after a total lifetime of 13–17 minutes, regardless of whether it's actively running a transaction. Sessions can be lost or impaired for a number of reasons, such as hardware failure, network failure, or application restarts. QLDB enforces a maximum lifetime on sessions to ensure that the client application is resilient to session failure.

Session handling in the QLDB driver

Although you can use an AWS SDK to interact directly with the QLDB Session API, this adds complexity and requires you to compute a commit digest. QLDB uses this commit digest to ensure transaction integrity. Instead of interacting directly with this API, we recommend using the QLDB driver.

The driver provides a high-level abstraction layer above the transactional data API. It streamlines the execution of PartiQL statements on ledger data by managing SendCommand API calls. These API calls require several parameters that the driver handles for you, including the management of sessions, transactions, and retry policy in case of errors.

Session pooling overview

In older versions of the QLDB driver (for example, Java v1.1.0), we provided two implementations of the driver object: a standard, nonpooled QldbDriver and a PooledQldbDriver. As the name suggests, the PooledQldbDriver maintains a pool of sessions that are reused across transactions.

Based on user feedback, developers prefer to get the pooling feature and its benefits by default, instead of using the standard driver. So, we removed the PooledQldbDriver and moved the session-pooling functionality to QldbDriver. This change is included in the latest release of each driver (for example, Java v2.0.0).

The driver provides three levels of abstractions:

  • Driver (pooled driver implementation) – The top-level abstraction. The driver maintains and manages a pool of sessions. When you ask the driver to run a transaction, the driver chooses a session from the pool and uses it to run the transaction. If the transaction fails because of a session error (InvalidSessionException), the driver uses another session to retry the transaction. Essentially, the driver offers a fully managed session experience.

  • Session – One level below the driver abstraction. A session is contained in a pool, and the driver manages the lifecycle of the session. If a transaction fails, the driver retries it up to a specified number of attempts using the same session. But if the session encounters an error (InvalidSessionException), QLDB discards it internally. The driver is then responsible for getting another session from the pool to retry the transaction.

  • Transaction – The lowest level of abstraction. A transaction is contained in a session, and the session manages the lifecycle of the transaction. The session is responsible for retrying the transaction in the case of an error. The session also ensures that it doesn't leak an open transaction that has not been committed or canceled.

In the latest version of each driver, you can perform operations at the driver level of abstraction only. You have no direct control over individual sessions and transactions (that is, there are no API operations to manually start a new session or transaction).

Session pooling and transaction logic

The latest release of each driver no longer provides a nonpooled implementation of the driver object. By default, the QldbDriver object manages the session pool. When you make a call to run a transaction, the driver does the following steps:

  1. The driver checks if it has reached the session-pool limit. If so, the driver immediately throws a NoSessionAvailable exception. Otherwise, it proceeds to the next step.

  2. The driver checks if the pool has an available session.

    • If a session is available in the pool, the driver uses it to run a transaction.

    • If no session is available in the pool, the driver creates a new session and uses it to run a transaction.

  3. After the driver gets a session in step 2, the driver calls the execute method on the session instance.

  4. In the execute method of the session, the driver tries to start a transaction by calling startTransaction.

    • If the session isn't valid, the startTransaction call fails, and the driver returns to step 1.

    • If the startTransaction call succeeds, the driver proceeds to the next step.

  5. The driver runs your lambda expression. This lambda expression can contain one or more calls to run PartiQL statements. After the lambda expression finishes running without any errors, the driver proceeds to commit the transaction.

  6. The commit of the transaction can have one of two results:

    • The commit succeeds, and the driver returns control to your application code.

    • The commit fails due to an optimistic concurrency control (OCC) conflict. In this case, the driver retries steps 4–6 using the same session. The maximum number of retry attempts is configurable in your application code. The default limit is 4.

Note

If an InvalidSessionException is thrown during steps 4–6, the driver marks the session as closed and returns to step 1 to retry the transaction.

If any other exception is thrown during steps 4–6, the driver checks if the exception can be retried. If so, it retries the transaction up to the specified number of retry attempts. If not, it propagates (bubbles up and throws) the exception to your application code.

Returning sessions to the pool

If an InvalidSessionException occurs at any time during the course of an active transaction, the driver doesn't return the session to the pool. QLDB discards the session instead, and the driver gets another session from the pool. In all other cases, the driver returns the session to the pool.