Transaction Management

 This page contains information and reference about the following topics/questions/how to's

  1. How to setup an applicatoin managed transaction manager (RESOURCE_LOCAL) in your web-app
  2. How to setup multiple transaction managers (multiple transactional data-sources)
  3. How to configure a transaction manager for unit-testing locally
  4. @Transactional Annotation best practices

Architecture Overview

How/Where an Entity Fits Overall

See Java Persistence API Architecture:

The diagram below illustrates the relationships between the primary components of the JPA architecture.

JPA Architecture Primary Components

Transaction Manager

 To gain an undestanding of JPA and Spring Transction Management, Please refer to:

Best Practices & How To's

Persistence-unit transaction-type: RESOURCE_LOCAL vs. JTA

  • Recommend RESOURCE_LOCAL: Most applications do NOT need to access a global transaction manager, hence the use of RESOURCE_LOCAL
  • RESOURCE_LOCAL means transactions are visible to the application and not globally
  • JTA: requires a full-blown J2EE server which tomcat is NOT. hence if you need to use this within tomcat you need to use a 3rd party library
    • recommend:Atomikos JTA transaction manager, since it's open-source, free and easy to configure
    • note: do NOT use JTA unless you are faimiliar with Java Transaction API (JTA)

@Transactional Annotation, DAO vs. Service Layer: which to annotate

  • Service layer should be annotated, since it's the one that knows about units of work and use cases
  • Benefits & Resaons
    • A Service might make use of various DAOs to achieve what it needs, i.e. If you have several DAOs injected into a Service that need to work together in a single transaction
    • For best performance annotating @Transactional is more appropriate

@Transactional Annotation, when to annotate at the service layer

Transactional Annotations should be placed around all operations that are inseparable.

For example, your call is "change password". That consists of three operations

  1. change the password
  2. audit the change
  3. email the client that the password has changed

So in the above, if the audit fails, then should the password change also fail? If so, then the transaction should be around 1 and 2 (so at the service layer). If the email fails (probably should have some kind of fail safe on this so it won't fail) then should it roll baack the change password and the audit?

These are the kind of questions you need to be asking when deciding where to put the @Transactional.

Declarative vs. Pragmatic Transaction Management: which to use

  • Declarative should be used for most applications
  • Benefits & Resaons
    • Most Flexibility & Portability
    • Least Invasive Lightweight using AOP

One Transaction Manager per Persistence Unit

  • see "Dealing with multiple persistence units" in Spring Docs
  • We recommend using a declarative approach to make use of the transaction manager
    • see Provided JPA/Spring Template and Properties file:
      • Transaction Manager
      • 1) create a transaction manager
        2) inject it into the entiry manager factory (see Entity Management)
        *
            <!-- ******************************************************************** -->
            <!-- Mark bean transactions as annotation driven -->
            <!-- ******************************************************************** -->
            <tx:annotation-driven transaction-manager="$[WEBAPPNAME]_pu_01_TransactionManager" />
        
            <!-- ******************************************************************** -->
            <!-- Setup the transaction manager -->
            <!-- ******************************************************************** -->
            <bean id="$[WEBAPPNAME]_pu_01_TransactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
                <property name="entityManagerFactory" ref="$[WEBAPPNAME]_pu_01_EntityManager" />
            </bean> 
        ...
        *
        

Spring Declarative Rollback Rules

The Spring Framework offers declarative rollback rules: a feature with no EJB equivalent, which we'll discuss below. Rollback can be controlled declaratively, not merely programmatically.

  • read "Declarative transaction management" in Spring Docs

ReadOnly @Transactional Hint

You can imporve performance and optimize your app by using read-only data-sources (set "readOnly=true" in you JNDI data-source in server.xml)

  • Also, as part of @Transactional Specifications a "readOnly" flag is provided
    • this hins to to the data-base a read-only transaction
    • the exact behavior of the flag is not guaranteed as per persistence provided might act differently depending on the use-case
    • In general a readOnly flag to the JPA provider means setting the "FlushMode.NEVER" i.e. since readOnly the current persistence session is prevented from commiting the transaction
    • In general a readOnly flag to the data-base is just a "HINT" hence we encourage the use of readOnly data-sources for best performance when appropriate
    • ...
         @Transactional(readOnly=true)
         Set<Fund> runFundReportByFundNumber(String fundNumber){...}
      ...
      

@Transactional Options/Settings

  • Alert: Please do NOT set any propagation flags if are NOT familiar with this topic
  • Propagation Strategies: please see Spring Docs: Topic: Transaction propagation

@Transactional Exceptions and RollBacks

  • You can spcify what exceptions will cause a transaction rollback
  • Default RollBack (Unchecked exceptions, RuntimeException): Spring Framework's transaction infrastructure code only marks a transaction for rollback in the case of runtime, unchecked exceptions; that is, when the thrown exception is an instance or subclass of RuntimeException. (Errors will also - by default - result in a rollback) 
  • Checked exceptions that are thrown from a transactional method do not result in rollback in the default configuration
  • see Spring Docs @Transactional settings

Unit Testing

  • See the Unit Testing section for sample code
    • define rollback rules on your unit-test
      •  @Rollback(true)

    • by default Spring assumes a Transaction Manager by the name of "transactionManager"
      • you will most likely name your transaction manager differently in case of multiple data-sources
        • use the following annotation on your unit-test class to specify the transaction manager
          •  @TransactionConfiguration(transactionManager="your_TransactionManager")

Governance

  • When possible use the @Transactional annotation on the Service Layer
  • We might not be able to help you If you decide to not follow the the provided template when configuring a transaction manager
  • Do not specify @Transactional Options/Settings when in doubt
  • Use readOnly data-sources (configured in server.xml) when running reports

Advanced

For an in depth overview of Spring and EJB/JPA transaction management please consult the following

References