Welcome!

Open Source Authors: Maureen O'Gara, Jeremy Geelan, Liz McMillan, Reuven Cohen, Lavenya Dilip

Related Topics: Open Source, Java

Open Source: Article

Bringing Advanced Transaction Capabilities to Spring Applications

Inversion of control and dependency injection

The BankImpl class extends the Spring JdbcDaoSupport class and uses the Spring JdbcTemplate to act on the bankDataSource datasource.

public class BankImpl extends JdbcDaoSupport implements Bank {

    public int selectBalance() {
       return getJdbcTemplate().queryForInt("select balance from bank where account = '101'");
    }

    public int selectBalanceForUpdate() {
       return getJdbcTemplate().queryForInt("select balance from bank where account = '101' for update");
    }

    public void updateBalance(int amount) {
       getJdbcTemplate().execute("update bank set balance = " + amount + " where account = '101'");
    }
}

The BrokerageImpl class extends the Spring JdbcDaoSupport class and uses the Spring JdbcTemplate to act on the brokerageDataSource datasource.

public class BrokerageImpl extends JdbcDaoSupport implements Brokerage {

    public List selectAllStocks() {
       return getJdbcTemplate().queryForList("select * from brokerage");
    }

    public void insertStock(String symbol, int amount) {
       getJdbcTemplate().execute("insert into brokerage values ('"+symbol+"', '"+amount+"' )");
    }
}

Let's look at the configuration files. The J2EE standard web-app descriptor web.xml includes a Spring ContextLoaderListener. The ContextLoaderListener causes the WEB-INF/applicationContext.xml specified by the contextConfigLocation context-param to be loaded by the Spring Framework.

The Spring DispatcherServlet servlet deployed with the servlet-name jta-spring causes the jta-spring-servlet.xml to be loaded by the Spring Framework.

<web-app>
   <display-name>JTA Spring Integration WebApp</display-name>

   <context-param>
     <param-name>contextConfigLocation</param-name>
     <param-value>WEB-INF/applicationContext.xml</param-value>
   </context-param>
    <listener>
       <listener- class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <servlet>
       <servlet-name>jta-spring</servlet-name>
       <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
       <load-on-startup>2</load-on-startup>
    </servlet>
    <servlet-mapping>
       <servlet-name>jta-spring</servlet-name>
       <url-pattern>JTADispatcherServlet</url-pattern>
   </servlet-mapping>
   <welcome-file-list>
       <welcome-file>index.html</welcome-file>
       </welcome-file-list>
</web-app>

The descriptor jta-spring-servlet.xml contains a bean definition for the HowToJTASpringController, namely the financialService bean named financial (the property name corresponds to the setter in HowToJTASpringController).

<beans>
    <bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="urlMap">
    <map>
       <entry key="*"><ref local="testController"/></entry>
    </map>
     </property>
    </bean>
    <bean id="testController" class="how.to.spring.tx.HowToJTASpringController">
       <property name="financial"><ref bean="financialService"/></property>
    </bean>
</beans>

The descriptor ApplicationContext.xml contains bean definitions for the FinancialServiceImpl, AssetManagementServiceImpl, BankImpl, and BrokerageImpl classes. The <tx:annotation-driven/> element specifies support for annotationdriven demarcation of transactions.
Finally, the descriptor specifies OC4JJtaTransactionManager as the transactionManager to be used.

<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:aop="http://www.springframework.org/schema/aop"
   xmlns:tx="http://www.springframework.org/schema/tx"
   xsi:schemaLocation="
   http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
   http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
   http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
   <bean id="attributes" class="org.springframework.metadata.commons.CommonsAttributes"/>
   <bean id="bankDAO" class="how.to.spring.tx.BankImpl">
     <property name="dataSource">
       <ref bean="bankDataSource"/>
     </property>
   </bean>
   <bean id="bankDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
     <property name="jndiName">
       <value>jdbc/bankDataSource</value>
     </property>
   </bean>
   <bean id="brokerageDAO" class="how.to.spring.tx.BrokerageImpl">
     <property name="dataSource">
       <ref bean="brokerageDataSource"/>
     </property>
   </bean>
<bean id="brokerageDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
     <property name="jndiName">
       <value>jdbc/brokerageDataSource</value>
     </property>
   </bean>
   <bean id="assetManagementService" class="how.to.spring.tx.AssetManagementServiceImpl">
     <property name="brokerage">
       <ref local="brokerageDAO"/>
     </property>
     <property name="bank">
       <ref local="bankDAO"/>
     </property>
   </bean>
   <bean id="financialService" class="how.to.spring.tx.FinancialServiceImpl">
     <property name="assetManagement">
       <ref local="assetManagementService"/>
     </property>
   </bean>
   <!-- enable the configuration of transactional behavior based on annotations -->
   <tx:annotation-driven/>
   <bean id="transactionManager" class="org.springframework.transaction.jta.OC4JJtaTransactionManager"/>
<!-- enable the configuration of transactional behavior based on xml
   <aop:config>
     <aop:pointcut id="financialOperations" expression="execution(* how.to.spring.tx.*.*(..))"/>
     <aop:advisor pointcut-ref="financialOperations" advice-ref="txAdvice"/>
   </aop:config>
   <tx:advice id="txAdvice">
     <tx:attributes>
       <tx:method name="processFinancials" read-only="true" propagation = "REQUIRED" isolation = "SERIALIZABLE"/>
       <tx:method name="reportAllAssets" propagation = "SUPPORTS"
       no-rollback-for="org.springframework.dao.ConcurrencyFailureException"/>
       <tx:method name="purchaseNewStockAndReport" propagation = "REQUIRES_NEW" isolation = "READ_COMMITTED"/>
     </tx:attributes>
   </tx:advice>
-->
</beans>

In this example we've discussed how to develop a simple Spring-enabled JTA application using the OC4JJtaTransactionManager to automatically provide named transactions and per-transaction isolation levels.

Summary
Spring aims to make J2EE development easier by using inversion of control as one of its central features. This enables you to develop enterprise applications using simple Java objects that collaborate with each other through interfaces. These beans are wired together at runtime by the Spring Container.

Staying true to assisting enterprise development and filling out its support for the middle tier, Spring offers integration with various J2EE services. It also provides integration with several transaction strategies and supports a variety of transaction scenarios, including integration with enterprise JTA transactioning systems.

www.oracle.com/technology/tech/java/oc4j/11/how_to/ how-to-jta-spring/doc/how-to-jta-spring.html

More Stories By Frances Zhao

Frances Zhao is a principal product manager in the Oracle Fusion Middleware team. Her focus is on the core J2EE container.

More Stories By Paul Parkinson

Paul Parkinson has been working with and developing transaction processing technology for 15 years. His work at Oracle includes the development of the Java Transaction API and Java Transaction Service implementations in the OC4J application server as well as performance and high-availability features, Web Service Transactions, and transactional aspects of JCA.

Comments (2) View Comments

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.


Most Recent Comments
Guy Pardon 07/24/07 08:58:32 AM EDT

(Trying again - link not property showing in my first post)

A complete working JMS/JDBC application with Spring JTA integration can be found here:

http://www.onjava.com/pub/a/onjava/2006/02/08/j2ee-without-application-s...

Guy Pardon 07/24/07 08:56:16 AM EDT

Nice article, though the sample application seems a bit exotic (2 databases are being combined in a synchronous, tighly-coupled integration scenario). More common is a loosely-coupled architecture where you have one (JMS) queue and one database - banks are also more likely to work that way.

A complete working JMS/JDBC application with Spring JTA integration can be found here:

www.onjava.com/pub/a/onjava/2006/02/08/j2ee-without-application-server.html

more (and in-depth) info on Spring's transaction configuration options is in following presentation:

http://media.techtarget.com/tss/BeJUG/J2EEAppsSpring/player.html

Disclaimer: I should mention that I am the author of both these publications, and heavily involved in some of the related technologies.

Best
Guy