# Transaction

Transactions are critical to maintaining data integrity. They are used to group operations into units of work that act in an all-or-nothing fashion. Transactions have the following qualities:

- Atomicity. Atomicity refers to the all-or-nothing property of transactions. Either every data update in the transaction completes successfully, or they all fail, leaving the datastore in its original state. A transaction cannot be only partially successful.

  atomicity transactions
  transactions atomicity

- Consistency. Each transaction takes the datastore from one consistent state to another consistent state.

  consistency transactions
  transactions consistency

- Isolation. Transactions are isolated from each other. When you are reading persistent data in one transaction, you cannot "see" the changes that are being made to that data in other transactions. Similarly, the updates you make in one transaction cannot conflict with updates made in concurrent transactions. The form of conflict resolution employed depends on whether you are using pessimistic or optimistic transactions. Both types are described later in this chapter.

  isolation transactions
  transactions isolation

- Durability. The effects of successful transactions are durable; the updates made to persistent data last for the lifetime of the datastore.

  durability transactions
  transactions durability

Together, these qualities are called the ACID properties of transactions. To understand why these properties are so important to maintaining data integrity, consider the following example:

ACID transactions
transactions ACID

Suppose you create an application to manage bank accounts. The application includes a method to transfer funds from one user to another, and it looks something like this:

    public void transferFunds(User from, User to, double amnt) {
        from.decrementAccount(amnt);
        to.incrementAccount(amnt);
    }

Now suppose that user Alice wants to transfer 100 dollars to user Bob. No problem; you simply invoke your transferFunds method, supplying Alice in the `from` parameter, Bob in the `to` parameter, and `100.00` as the `amnt` . The first line of the method is executed, and 100 dollars is subtracted from Alice's account. But then, something goes wrong. An unexpected exception occurs, or the hardware fails, and your method never completes.

You are left with a situation in which the 100 dollars has simply disappeared. Thanks to the first line of your method, it is no longer in Alice's account, and yet it was never transferred to Bob's account either. The datastore is in an inconsistent state.

The importance of transactions should now be clear. If the two lines of the transferFunds method had been placed together in a transaction, it would be impossible for only the first line to succeed. Either the funds would be transferred properly or they would not be transferred at all, and an exception would be thrown. Money could never vanish into thin air, and the data store could never get into an inconsistent state.

## Transaction Types

There are two major types of transactions: pessimistic transactions and optimistic transactions. Each type has both advantages and disadvantages.

Pessimistic transactions generally lock the datastore records they act on, preventing other concurrent transactions from using the same data. This avoids conflicts between transactions, but consumes database resources. Additionally, locking records can result in deadlock, a situation in which two transactions are both waiting for the other to release its locks before completing. The results of a deadlock are datastore-dependent; usually one transaction is forcefully rolled back after some specified timeout interval, and an exception is thrown.

transactions pessimistic
pessimistic transactions transactions, pessimistic
deadlock transactions

This document will often use the term datastore transaction in place of pessimistic transaction. This is to acknowledge that some datastores do not support pessimistic semantics, and that the exact meaning of a non-optimistic JPA transaction is dependent on the datastore. Most of the time, a datastore transaction is equivalent to a pessimistic transaction.

transactions datastore
datastore transactions transactions, datastore

Optimistic transactions consume less resources than pessimistic/datastore transactions, but only at the expense of reliability. Because optimistic transactions do not lock datastore records, two transactions might change the same persistent information at the same time, and the conflict will not be detected until the second transaction attempts to flush or commit. At this time, the second transaction will realize that another transaction has concurrently modified the same records (usually through a timestamp or versioning system), and will throw an appropriate exception. Note that optimistic transactions still maintain data integrity; they are simply more likely to fail in heavily concurrent situations.

transactions optimistic
optimistic transactions transactions, optimistic

Despite their drawbacks, optimistic transactions are the best choice for most applications. They offer better performance, better scalability, and lower risk of hanging due to deadlock.

OpenJPA uses optimistic semantics by default, but supports both optimistic and datastore transactions. OpenJPA also offers advanced locking and versioning APIs for fine-grained control over database resource allocation and object versioning. See of the Reference Guide for details on locking. of this document covers standard object versioning, while of the Reference Guide discusses additional versioning strategies available in OpenJPA.

transactions types

## The EntityTransaction Interface

JPA integrates with your container's managed transactions, allowing you to use the container's declarative transaction demarcation and its Java Transaction API (JTA) implementation for transaction management. Outside of a container, though, you must demarcate transactions manually through JPA. The EntityTransaction interface controls unmanaged transactions in JPA.

    public void begin();
    public void commit();
    public void rollback();

The begin, commit, and rollback methods demarcate transaction boundaries. The methods should be self-explanatory: begin starts a transaction, commit attempts to commit the transaction's changes to the datastore, and rollback aborts the transaction, in which case the datastore is "rolled back" to its previous state. JPA implementations will automatically roll back transactions if any exception is thrown during the commit process.

Transaction demarcation
transactions demarcating
Transaction begin
Transaction commit
Transaction rollback

Unless you are using an extended persistence context, committing or rolling back also ends the persistence context. All managed entities will be detached from the EntityManager.

    public boolean isActive();

Finally, the isActive method returns `true` if the transaction is in progress (begin has been called more recently than commit or rollback), and `false` otherwise.

Transaction isActive

Grouping Operations with Transactions

    public void transferFunds(EntityManager em, User from, User to, double amnt) {
        // note: it would be better practice to move the transaction demarcation
        // code out of this method, but for the purposes of example...
        Transaction trans = em.getTransaction();
        trans.begin();
        try
        {
            from.decrementAccount(amnt);
            to.incrementAccount(amnt);
            trans.commit();
        }
        catch (RuntimeException re)
        {
            if (trans.isActive())
                trans.rollback();   // or could attempt to fix error and retry
            throw re;
        }
    }

Transaction transactions
transactions Transaction