Showing posts with label Spring Transactions. Show all posts
Showing posts with label Spring Transactions. Show all posts

Thursday, June 7, 2012

JTA Transaction Manager(XA) - Analysis


Requirements
We needs JTA complaint XA transaction manager since we have multiple resources
  • Database - Mysql
  • Cache - Infinispan
Both of these resources support XA - JTA transactions. - Mysql through com.mysql.jdbc.jdbc2.optional.MysqlXADataSource.
Alternatives for transaction manager 
We also need to choose a connection pool framework for database which is XA complaint. Hence options
Picking the right combination
  1. Atomokis transaction Manager + Atomikos connection pooling 
  • Easy configurations with Spring
  • JTA implementation comes with connection Pooling & Datasource (no need of seperate JCA)
  • Does support synchronization
  • Does not support last resource optimization
2. Jboss transaction Manager

      Jboss does not come with default connection pool  or JCA to be used in Standalone mode. Hence it is ideal with server liek Jboss and not in standalone mode
       Issues 
   1. Tried Jboss TM + DBCl Connection pool(XA) as suggested in  - http://lafernando.com/2011/01/05/xa-transactions-with-apache-dbcp/
   Faced issues were in connections got exhasted and where not returned to the pool
  2. Then tried to replace DBCP with Tomcat jdbc pool - which is the advanced version of dbcp overcoming its drawbacks
   Even though jdbc pool claims to have XA support , did not find much info about it in the net. When I tried the datasource did not seem to take part in the transaction.
 So the optiosn for JCA where 
Both these did not have any great documentation for use in standalone environment.
Based on all the above we will switch back to Atomikos  because
  1. It has Support
  2. Good documentation/ examples
  3. Seems to be widely used

Wednesday, May 16, 2012

Spring Configurations for JTA Transaction - XA datasource (Mysql) + Jboss Transaction manager(Arjuna) + Spring Transaction annotations + DBCP Connection pooling

Mysql complaint mysql xa datasource and Atomikos connection pooling

     
   
   
   
     
  
   
        
        
    

    
     
     
    
    
    
        
        
        
        
        false
        true
    

    
    
        
  
    


Jboss transaction manager settings

 
 


 
 

 


 
  
   
  
  
   
  
 

Maven dependencies for dbcp and jboss transaction manager

              4.16.4.Final

  
    commons-dbcp
    commons-dbcp
    1.4
  

  
   org.jboss.jbossts
   jbossjta
   ${jboss.jta.version}
  




Friday, May 11, 2012

Spring Configuratiosn for JTA Transaction - XA datasource (Mysql) + Atomikos Transaction manager + Spring Transaction annotations





Mysql complaint mysql xa datasource  and Atomikos connection pooling



 <bean id="dataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean"
  init-method="init" destroy-method="close">
  <property name="uniqueResourceName" value="MAIN-ATOMIKOS-CONNECTION" />
  <property name="poolSize" value="${initialSize}" />
  <property name="xaDataSourceClassName"
   value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource" />
  <property name="xaProperties" ref="databaseProperties" />
  <property name="testQuery" value="select 1" />
 </bean>




database.properties


<util:properties id="databaseProperties"
  location="classpath:database.properties" />



url=jdbc\:mysql\://localhost\:3306/<DBNAME>
user=root
password=
autoReconnect=true
autoReconnectForConnectionPools=true
autoReconnectForPools=true
pinGlobalTxToPhysicalConnection=true


Transaction specific Config

Following settings are for enabling transactions

<tx:annotation-driven transaction-manager="transactionManager" />

<bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager" 
  init-method="init" destroy-method="close"> 
           <property name="forceShutdown"> <value>true</value> </property> 
</bean>

<bean id="atomikosUserTransaction" 
  class="com.atomikos.icatch.jta.UserTransactionImp">
            <property name="transactionTimeout" 
  value="300"/> 
</bean> 

<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"> 
  <property name="transactionManager"> <ref bean="atomikosTransactionManager" 
  /> </property> 
              <property name="userTransaction"> <ref bean="atomikosUserTransaction" 
  /> </property> 
</bean> 




Just adding spring Spring annotation - will now enable transaction on required methods.


Friday, February 4, 2011

Unit test framework with Liquibase+HsqlDb+Spring transactions

When looking at options for testing DAO classes I came up with a framework using the following

1. Liquibase - For maintaing data/schema scripts

2. HSQLDB - Inmemory database for test cases

3. Spring transactions - For maintaining clean state between two test cases which make DB updates i .e all data changes made by the test cases will be rolled back by the end of the test case.


I am using spring beans to initialize all the above. I will explain each of them in detail.

1. Initializing the HSQLDB



<context:property-placeholder
location="classpath*:tspex-test-inmemorydatabase.properties" />

<bean id="hsqlDataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${database.driverClassName}">
<property name="url" value="${database.url}">
<property name="username" value="${database.username}">
<!-- <property name="password" value="${jdbc.password}"> -->
</bean>



All the values will be picked up from the file mentioned in the classpath.

2. Setting up Liquibase

I am using the following method to initialize Liquibase



public class TestFramework {

private DataSource dataSource;

public void initializeLiquiBase(String changeLogFile) throws Exception {
Connection conn = dataSource.getConnection();
Liquibase liquibase = new Liquibase(changeLogFile,
new ClassLoaderResourceAccessor(), new HsqlConnection(conn));
// Uncomment the following line when testing with mysql database
/*
* Liquibase liquibase = new Liquibase(changeLogFile, new
* ClassLoaderResourceAccessor(), new JdbcConnection(conn));
*/

liquibase.update("");
conn.close();
}

public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}

}



Corresponding spring configuration.



<bean id="testFramework" class="com.mycompany.framework.unittest.TestFramework">
<property name="dataSource" ref="hsqlDataSource">
</bean>



The changeLogFile will be provided by the user of the frame work , which i will explain shortly.


3. Setting up Spring transactions.



<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="hsqlDataSource">
</bean>

<tx:annotation-driven manager="transactionManager">



These are the only classes/configuration present in my framework

The maven dependencies required are as follows



<dependency>
<groupid>org.hsqldb</groupid>
<artifactid>hsqldb</artifactid>
<version>2.0.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupid>org.liquibase</groupid>
<artifactid>liquibase-core</artifactid>
<version>2.0.0</version>
</dependency>
<dependency>
<groupid>org.liquibase</groupid>
<artifactid>liquibase-plugin</artifactid>
<version>1.9.5.0</version>
</dependency>
<dependency>
<groupid>junit</groupid>
<artifactid>junit</artifactid>
<version>4.7</version>
</dependency>



Now let me explain how the framework will be used by the classes testing the framework


A typical test class for DAO will be as follows



@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
"classpath*:/META-INF/spring/unit-test-framework-module-context.xml",
"classpath*:/META-INF/spring/test-spring-jdbc-module-context.xml" })
public class TestAccountDAOSpringJdbc {

@Autowired
private TestFramework testFramework;

@Autowired
private AccountDAOSpringJdbc accountDao;

@Test
public void setUpBeforeClass() throws Exception {
System.out.println("Setup before class called");
testFramework.initializeLiquiBase("accounts-data-changelog-1.0.xml");


@Test
@Transactional
public void testSaveUpdate() throws Exception {
// Create a new Account
Account account = accountDao.get(1);
account.setUsername("newaccount");
account.setTitle("Mr");

........


}



The important thing to note here are

1. Initializing the framework beans - which contains HSQLDB and spring transaction initialization.

2. Initializing the test framework with liquibase scripts

This ensure that the database tables are created and test data is inserted before test cases run.

Ref: http://www.liquibase.org/

3. Using @Transactional annotation before test cases which updates the Database . This ensures that test cases do not commit anything into DB and all test cases can be independent of each other.

With some infrastructure setup like this , writing test cases for DAO become very easy.

 
Free Domain Names @ .co.nr!