<?xml version='1.0' encoding='utf-8' ?>

<!--
  ~ Hibernate, Relational Persistence for Idiomatic Java
  ~
  ~ License: GNU Lesser General Public License (LGPL), version 2.1 or later.
  ~ See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
  -->
<chapter xml:id="transactions"
         xmlns="http://docbook.org/ns/docbook"
        xmlns:xi="http://www.w3.org/2001/XInclude">

    <title>Transactions and concurrency control</title>

    <para>
        It is important to understand that the term transaction has many different yet related meanings in regards
        to persistence and Object/Relational Mapping.  In most use-cases these definitions align, but that is not
        always the case.
    </para>
    <itemizedlist>
        <listitem>
            <para>
                Might refer to the physical transaction with the database.
            </para>
        </listitem>
        <listitem>
            <para>
                Might refer to the logical notion of a transaction as related to a persistence context.
            </para>
        </listitem>
        <listitem>
            <para>
                Might refer to the application notion of a Unit-of-Work, as defined by the archetypal pattern.
            </para>
        </listitem>
    </itemizedlist>

    <note>
        <para>
            This documentation largely treats the physical and logic notions of transaction as one-in-the-same.
        </para>
    </note>


    <section xml:id="transactions-physical">
        <title>Physical Transactions</title>
        <para>
            Hibernate uses the JDBC API for persistence.  In the world of Java there are 2 well defined mechanism
            for dealing with transactions in JDBC: JDBC itself and JTA.  Hibernate supports both mechanisms for
            integrating with transactions and allowing applications to manage physical transactions.
        </para>

        <para>
            Transaction handling per Session is handled by the
            <interfacename>org.hibernate.resource.transaction.TransactionCoordinator</interfacename> contract, which
            are built by the <interfacename>org.hibernate.resource.transaction.TransactionCoordinatorBuilder</interfacename>
            service.  TransactionCoordinatorBuilder represents a strategy for dealing with transactions whereas
            TransactionCoordinator represents one instance of that strategy related to a Session.  Which
            TransactionCoordinatorBuilder implementation to use is defined by the
            <literal>hibernate.transaction.coordinator_class</literal> setting.
        </para>

        <itemizedlist>
            <title>Hibernate-provided TransactionCoordinatorBuilder implementations</title>
            <listitem>
                <para>
                    <literal>jdbc</literal> (the default) - Manages transactions via calls to <interfacename>java.sql.Connection</interfacename>
                </para>
            </listitem>
            <listitem>
                <para>
                    <literal>jta</literal> - Manages transactions via JTA.  See <xref linkend="bootstrap-jtaplatform"/>
                </para>
            </listitem>
        </itemizedlist>

        <note>
            <para>
                For details on implementing a custom TransactionCoordinatorBuilder, or simply better understanding
                how it works, see the <citetitle>Integrations Guide</citetitle>
            </para>
        </note>

        <para>
            Hibernate uses JDBC connections and JTA resources directly, without adding any additional locking behavior.
            Hibernate does not lock objects in memory.  The behavior defined by the isolation level of your database
            transactions does not change when you use Hibernate.  The Hibernate Session acts as a transaction-scoped
            cache providing repeatable reads for lookup by identifier and queries that result in loading entities.
        </para>

        <important>
            <para>
                To reduce lock contention in the database, the physical database transaction needs to be as short as
                possible.  Long database transactions prevent your application from scaling to a highly-concurrent load.
                Do not hold a database transaction open during end-user-level work, but open it after the end-user-level
                work is finished.  This is concept is referred to as <literal>transactional write-behind</literal>.
            </para>
        </important>

        <section xml:id="transactions-physical-jtaplatform">
            <title>JTA configuration</title>

            <para>
                Interaction with a JTA system is consolidated behind a single contract named
                <interfacename>org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform</interfacename> which
                exposes access to the <interfacename>javax.transaction.TransactionManager</interfacename> and
                <interfacename>javax.transaction.UserTransaction</interfacename> for that system as well as exposing
                the ability to register <interfacename>javax.transaction.Synchronization</interfacename> instances,
                check transaction status, etc.
            </para>

            <note>
                <para>
                    Generally JtaPlatform will need access to JNDI to resolve the JTA TransactionManager,
                    UserTransaction, etc.  See <xref linkend="jndi"/> for details on configuring access
                    to JNDI
                </para>
            </note>

            <para>
                Hibernate tries to discover the JtaPlatform it should use through the use of another service named
                <interfacename>org.hibernate.engine.transaction.jta.platform.spi.JtaPlatformResolver</interfacename>.
                If that resolution does not work, or if you wish to provide a custom implementation you will need to
                specify the <literal>hibernate.transaction.jta.platform</literal> setting.  Hibernate provides many
                implementations of the JtaPlatform contract, all with short-names:
            </para>

            <itemizedlist>
                <title>Built-in JtaPlatform implementations by short name</title>
                <listitem>
                    <para>
                        <literal>Borland</literal> - JtaPlatform for the Borland Enterprise Server.
                    </para>
                </listitem>
                <listitem>
                    <para>
                        <literal>Bitronix</literal> - JtaPlatform for Bitronix.
                    </para>
                </listitem>
                <listitem>
                    <para>
                        <literal>JBossAS</literal> - JtaPlatform for Arjuna/JBossTransactions/Narnya when used within the JBoss/WildFly Application Server.
                    </para>
                </listitem>
                <listitem>
                    <para>
                        <literal>JBossTS</literal> - JtaPlatform for Arjuna/JBossTransactions/Narnya when used standalone.
                    </para>
                </listitem>
                <listitem>
                    <para>
                        <literal>JOnAS</literal> - JtaPlatform for JOTM when used within JOnAS.
                    </para>
                </listitem>
                <listitem>
                    <para>
                        <literal>JOTM</literal> - JtaPlatform for JOTM when used standalone.
                    </para>
                </listitem>
                <listitem>
                    <para>
                        <literal>JRun4</literal> - JtaPlatform for the JRun 4 Application Server.
                    </para>
                </listitem>
                <listitem>
                    <para>
                        <literal>OC4J</literal> - JtaPlatform for Oracle's OC4J container.
                    </para>
                </listitem>
                <listitem>
                    <para>
                        <literal>Orion</literal> - JtaPlatform for the Orion Application Server.
                    </para>
                </listitem>
                <listitem>
                    <para>
                        <literal>Resin</literal> - JtaPlatform for the Resin Application Server.
                    </para>
                </listitem>
                <listitem>
                    <para>
                        <literal>SunOne</literal> - JtaPlatform for the SunOne Application Server.
                    </para>
                </listitem>
                <listitem>
                    <para>
                        <literal>Weblogic</literal> - JtaPlatform for the Weblogic Application Server.
                    </para>
                </listitem>
                <listitem>
                    <para>
                        <literal>WebSphere</literal> - JtaPlatform for older versions of the WebSphere Application Server.
                    </para>
                </listitem>
                <listitem>
                    <para>
                        <literal>WebSphereExtended</literal> - JtaPlatform for newer versions of the WebSphere Application Server.
                    </para>
                </listitem>
            </itemizedlist>
        </section>
    </section>

    <section xml:id="transactions-api">
        <title>Hibernate Transaction API</title>

        <para>
            Hibernate provides an API for helping to isolate applications from the differences in the underlying
            physical transaction system in use.  Based on the configured TransactionCoordinatorBuilder, Hibernate
            will simply do the right thing when this transaction API is used by the application.  This allows your
            applications and components to be more portable move around into different environments.
        </para>

        <para>
            To use this API, you would obtain the <interfacename>org.hibernate.Transaction</interfacename>
            from the Session.
        </para>

        <para>
            Transaction allows for all the normal operations you'd expect.  <methodname>begin</methodname>,
            <methodname>commit</methodname> and <methodname>rollback</methodname>.  And these calls noop if they
            should.
        </para>

        <para>
            It even exposes some cool methods like:
            <itemizedlist>
                <listitem>
                    <methodname>markRollbackOnly</methodname> that works in both JTA and JDBC!
                </listitem>
                <listitem>
                    <methodname>getTimeout</methodname> and <methodname>setTimeout</methodname> that again work
                    in both JTA and JDBC!
                </listitem>
                <listitem>
                    <methodname>registerSynchronization</methodname> that allows you to register JTA Synchronizations
                    even in non-JTA environments.  In fact in both JTA and JDBC environments, these Synchronizations
                    are kept locally by Hibernate.  In JTA environments Hibernate will only ever register one single
                    Synchronization with the TransactionManager to avoid ordering problems.
                </listitem>
            </itemizedlist>
        </para>

        <para>
            Additionally it exposes a <methodname>getStatus</methodname> method that returns an
            <classname>org.hibernate.resource.transaction.spi.TransactionStatus</classname> enum.  This method
            checks with the underling transaction system if needed, so care should be taken to minimize its use;
            it can have a big performance impact in certain JTA set ups.
        </para>

        <para>
            Lets take a look at using the Transaction API in the various environments.
        </para>

        <example>
            <title>Using Transaction API in JDBC</title>
            <programlisting role="JAVA"><xi:include href="extras/jdbc.java" parse="text"/></programlisting>
        </example>

        <example>
            <title>Using Transaction API in JTA (CMT)</title>
            <programlisting role="JAVA"><xi:include href="extras/cmt.java" parse="text"/></programlisting>
        </example>

        <example>
            <title>Using Transaction API in JTA (BMT)</title>
            <programlisting role="JAVA"><xi:include href="extras/bmt.java" parse="text"/></programlisting>
        </example>

        <para>
            In the CMT case we really could have omitted all of the Transaction calls.  But the point of
            the examples was to show that the Transaction API really does insulate your code from the underlying
            transaction mechanism.  In fact if you strip away the comments and the single configruation
            setting supplied at bootstrap, the code is exactly the same in all 3 examples.  In other words,
            we could develop that code and drop it, as-is, in any of the 3 transaction environments.
        </para>

        <para>
            The Transaction API tries hard to make the experience consistent across all environments.  To that end,
            it generally defers to the JTA specification when there are differences (for example automatically trying
            rollback on a failed commit).
        </para>
    </section>

    <section>
        <title>Transactional patterns (and anti-patterns)</title>

        <section xml:id="session-per-operation">
            <title>Session-per-operation anti-pattern</title>
            <para>
                This is an anti-pattern of opening and closing a <classname>Session</classname> for each database call
                in a single thread.  It is also an anti-pattern in terms of database transactions. Group your database
                calls into a planned sequence.  In the same way, do not auto-commit after every SQL statement in your
                application.  Hibernate disables, or expects the application server to disable, auto-commit mode
                immediately.  Database transactions are never optional.  All communication with a database must
                be encapsulated by a transaction.  Avoid auto-commit behavior for reading data, because many small
                transactions are unlikely to perform better than one clearly-defined unit of work, and are more
                difficult to maintain and extend.
            </para>
            <note>
                <para>
                    Using auto-commit does not circumvent database transactions.  Instead, when in auto-commit mode,
                    JDBC drivers simply perform each call in an implicit transaction call.  It is as if your application
                    called commit after each and every JDBC call.
                </para>
            </note>
        </section>

        <section xml:id="session-per-request">
            <title>Session-per-request pattern</title>
            <para>
                This is the most common transaction pattern.  The term request here relates to the concept of a system
                that reacts to a series of requests from a client/user.  Web applications are a prime example of this
                type of system, though certainly not the only one.  At the beginning of handling such a request, the
                application opens a Hibernate <interfacename>Session</interfacename>, starts a transaction, performs
                all data related work, ends the transaction and closes the <interfacename>Session</interfacename>.
                The crux of the pattern is the one-to-one relationship between the transaction and the
                <interfacename>Session</interfacename>.
            </para>

            <para>
                Within this pattern there is a common technique of defining a <firstterm>current session</firstterm> to
                simplify the need of passing this <interfacename>Session</interfacename> around to all the application
                components that may need access to it.  Hibernate provides support for this technique through the
                <methodname>getCurrentSession</methodname> method of the <interfacename>SessionFactory</interfacename>.
                The concept of a "current" session has to have a scope that defines the bounds in which the notion
                of "current" is valid.   This is purpose of the
                <interfacename>org.hibernate.context.spi.CurrentSessionContext</interfacename> contract.  There are 2
                reliable defining scopes:
            </para>
            <itemizedlist>
                <listitem>
                    <para>
                        First is a JTA transaction because it allows a callback hook to know when it is ending which
                        gives Hibernate a chance to close the <interfacename>Session</interfacename> and clean up.
                        This is represented by the
                        <classname>org.hibernate.context.internal.JTASessionContext</classname> implementation of
                        the <interfacename>org.hibernate.context.spi.CurrentSessionContext</interfacename> contract.
                        Using this implementation, a <interfacename>Session</interfacename> will be opened the first
                        time <methodname>getCurrentSession</methodname> is called within that transaction.
                    </para>
                </listitem>
                <listitem>
                    <para>
                        Secondly is this application request cycle itself.  This is best represented with the
                        <classname>org.hibernate.context.internal.ManagedSessionContext</classname> implementation of
                        the <interfacename>org.hibernate.context.spi.CurrentSessionContext</interfacename> contract.
                        Here an external component is responsible for managing the lifecycle and scoping of a "current"
                        session.  At the start of such a scope, <classname>ManagedSessionContext</classname>'s
                        <methodname>bind</methodname> method is called passing in the
                        <interfacename>Session</interfacename>.  At the end, its <methodname>unbind</methodname>
                        method is called.
                    </para>
                    <para>
                        Some common examples of such "external components" include:
                    </para>
                    <itemizedlist>
                        <listitem>
                            <para>
                                <interfacename>javax.servlet.Filter</interfacename> implementation
                            </para>
                        </listitem>
                        <listitem>
                            <para>
                                AOP interceptor with a pointcut on the service methods
                            </para>
                        </listitem>
                        <listitem>
                            <para>
                                A proxy/interception container
                            </para>
                        </listitem>
                    </itemizedlist>
                </listitem>
            </itemizedlist>
            <important>
                <para>
                    The <methodname>getCurrentSession()</methodname> method has one downside in a JTA environment.  If
                    you use it, after_statement connection release mode is also used by default.  Due to a limitation of
                    the JTA specification, Hibernate cannot automatically clean up any unclosed
                    <interfacename>ScrollableResults</interfacename> or <interfacename>Iterator</interfacename>
                    instances returned by <methodname>scroll()</methodname> or <methodname>iterate()</methodname>.
                    Release the underlying database cursor by calling <methodname>ScrollableResults.close()</methodname>
                    or <methodname>Hibernate.close(Iterator)</methodname> explicitly from a
                    <systemitem>finally</systemitem> block.
                </para>
            </important>
        </section>

        <section xml:id="long-conversations">
            <title>Conversations</title>
            <para>
                The <phrase>session-per-request</phrase> pattern is not the only valid way of designing units of work.
                Many business processes require a whole series of interactions with the user that are interleaved with
                database accesses. In web and enterprise applications, it is not acceptable for a database transaction
                to span a user interaction. Consider the following example:
            </para>
            <procedure>
                <title>An example of a long-running conversation</title>
                <step>
                    <para>
                        The first screen of a dialog opens. The data seen by the user is loaded in a particular
                        <classname>Session</classname> and database transaction.  The user is free to modify the objects.
                    </para>
                </step>
                <step>
                    <para>
                        The user uses a UI element to save their work after five minutes of editing. The modifications
                        are made persistent.  The user also expects to have exclusive access to the data during the edit
                        session.
                    </para>
                </step>
            </procedure>

            <para>
                Even though we have multiple databases access here, from the point of view of the user, this series of
                steps represents a single unit of work.  There are many ways to implement this in your application.
            </para>

            <para>
                A first naive implementation might keep the <classname>Session</classname> and database transaction open
                while the user is editing, using database-level locks to prevent other users from modifying the same
                data and to guarantee isolation and atomicity.  This is an anti-pattern, because lock contention is a
                bottleneck which will prevent scalability in the future.
            </para>
            <para>
                Several database transactions are used to implement the conversation.  In this case, maintaining
                isolation of business processes becomes the partial responsibility of the application tier.  A single
                conversation usually spans several database transactions.  These multiple database accesses can only
                be atomic as a whole if only one of these database transactions (typically the last one) stores the
                updated data.  All others only read data.  A common way to receive this data is through a wizard-style
                dialog spanning several request/response cycles.  Hibernate includes some features which make this easy
                to implement.
            </para>

            <informaltable>
                <tgroup cols="2">
                    <tbody>
                        <row>
                            <entry>
                                <para>
                                    Automatic Versioning
                                </para>
                            </entry>
                            <entry>
                                <para>
                                    Hibernate can perform automatic optimistic concurrency control for you.  It can
                                    automatically detect if a concurrent modification occurred during user think time.
                                    Check for this at the end of the conversation.
                                </para>
                            </entry>
                        </row>
                        <row>
                            <entry>
                                <para>
                                    Detached Objects
                                </para>
                            </entry>
                            <entry>
                                <para>
                                    If you decide to use the session-per-request pattern, all loaded instances will be
                                    in the detached state during user think time.  Hibernate allows you to reattach the
                                    objects and persist the modifications.  The pattern is called
                                    session-per-request-with-detached-objects.  Automatic versioning is used to isolate
                                    concurrent modifications.
                                </para>
                            </entry>
                        </row>
                        <row>
                            <entry>
                                <para>
                                    Extended Session
                                </para>
                            </entry>
                            <entry>
                                <para>
                                    The Hibernate <interfacename>Session</interfacename> can be disconnected from the
                                    underlying JDBC connection after the database transaction has been committed and
                                    reconnected when a new client request occurs. This pattern is known as
                                    session-per-conversation and makes even reattachment unnecessary. Automatic
                                    versioning is used to isolate concurrent modifications and the
                                    <interfacename>Session</interfacename> will not be allowed to flush automatically,
                                    only explicitly.
                                </para>
                            </entry>
                        </row>
                    </tbody>
                </tgroup>
            </informaltable>

            <para>
                <phrase>Session-per-request-with-detached-objects</phrase> and <phrase>session-per-conversation</phrase>
                each have advantages and disadvantages.
            </para>
        </section>

        <section>
            <title>Session-per-application</title>
            <para>
                Discussion coming soon..
            </para>
        </section>
    </section>


    <section xml:id="transactions-basics-issues">
        <title>Common issues</title>

        <itemizedlist>
            <listitem>
                <para>
                    A Session is not thread-safe. Things that work concurrently, like HTTP requests, session beans,
                    or Swing workers, will cause race conditions if a Session instance is shared.  If you keep your
                    Hibernate Session in your <interfacename>javax.servlet.http.HttpSession</interfacename> you should
                    consider synchronizing access to your HttpSession; otherwise, a user that clicks reload fast enough
                    can use the same Session in two concurrently running threads.
                </para>
            </listitem>
            <listitem>
                <para>
                    An exception thrown by Hibernate means you have to rollback your database transaction
                    and close the Session immediately.  If your Session is bound to the application,
                    you have to stop the application.  Rolling back the database transaction does not put your business
                    objects back into the state they were at the start of the transaction.  This means that the
                    database state and the business objects will be out of sync. Usually this is not a
                    problem, because exceptions are not recoverable and you will have to start over after
                    rollback anyway.
                </para>
            </listitem>
            <listitem>
                <para>
                    The Session caches every object that is in a persistent state (watched and checked for changes
                    by Hibernate).  If you keep it open for a long time or simply load too much data, it will grow
                    endlessly until you get an OutOfMemoryException.  One solution is to call
                    <methodname>clear()</methodname> and <methodname>evict()</methodname> to manage the
                    Session cache, but you should consider an alternate means of dealing with large amounts of data
                    such as a Stored Procedure.  Java is simply not the right tool for these kind of operations.
                    Some solutions are shown in <xref linkend="batch"/>.  Keeping a Session open for the duration of
                    a user session also means a higher probability of stale data.
                </para>
            </listitem>
        </itemizedlist>

    </section>

</chapter>