Spring Transaction Examples

 

By Neeraj Verma 2008-11-14

 

Spring Transaction Examples. 1

Declarative Transactions. 1

Case Study. 1

Case Study. 1

Case Study. 3

Case study. 3

Case study. 4

 

 

Declarative Transactions

 

The following case studies test the transaction capabilities of the spring framework’s DataSourceTransactionManager.

 

Case Study

 

1. Create a model and make one of the methods transactional PROPAGATION_REQUIRED. Call the method and throw an exception.

-> This should roll back the database transaction.

 

 

Case Study

 

Description:

 

This case study has a TestModel calling a DataManager that is transaction enabled. The data manager’s method is coded to throw a RuntimeException after executing the insert statement.

 

Expected Results

The expected result is that the transaction will be rolled back since the datamanager’s method is transactional.

 

Summary of results:

Database changes were rolled back.

 

TestModel

 

public class TestModelImpl implements TestModel {

   private OrgPeopleDataManager orgPeopleDataManager;

  

  

   /* (non-Javadoc)

    * @see orgcommon.TestModel#initializeCountries()

    */

   public void initializeCountries() {

       orgPeopleDataManager.initializeCountries();

   }

   public void deleteAllCountries() {

       orgPeopleDataManager.deleteAllCountries();

   }

  

 

OrgPeopleDataManager

 

public class JdbcOrgPeopleDataManager implements OrgPeopleDataManager {

   private JdbcTemplate jdbcTemplate;

 

   public void deleteAllCountries() {

       jdbcTemplate.update("delete from country");

   }

   public void initializeCountries() {

       jdbcTemplate.update("insert into country values (1, 'test country', 'Test Country')");

       throw new RuntimeException("test");

   }

 

Test Case

package orgcommon;

 

 

public class AddCountryTest extends BaseTestCase {

   public void testAddCountry() {

       TestModel testModel = (TestModel) context.getBean("testModel");

       testModel.deleteAllCountries();

       testModel.initializeCountries();

   }

}

 

Configuration

   <bean name="orgPeopleDataManagerTarget" class="orgpeople.JdbcOrgPeopleDataManager"/>

 

 

   <bean id="orgPeopleDataManager"

       class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">

       <property name="transactionManager"><ref bean="transactionManager"/></property>

       <property name="target"><ref bean="orgPeopleDataManagerTarget"/></property>

       <property name="transactionAttributes">

           <props>

               <prop key="*">PROPAGATION_REQUIRED</prop>

           </props>

       </property>

   </bean>

      

   <bean name="testModel" class="orgcommon.TestModelImpl">

       <property name="orgPeopleDataManager" ref="orgPeopleDataManager"/>

   </bean>

 

 

Log output

 

0    [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Using transaction object [org.springframework.jdbc.datasource.DataSourceTransactionManager$DataSourceTransactionObject@c4bc34]

0    [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Creating new transaction with name [orgpeople.OrgPeopleDataManager.deleteAllCountries]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT

157  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Acquired Connection [com.mysql.jdbc.Connection@91f005] for JDBC transaction

157  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Switching JDBC Connection [com.mysql.jdbc.Connection@91f005] to manual commit

157  [main] DEBUG org.springframework.jdbc.core.JdbcTemplate  - Executing SQL update [delete from country]

172  [main] DEBUG org.springframework.jdbc.core.JdbcTemplate  - SQL update affected 0 rows

172  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Triggering beforeCommit synchronization

172  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Triggering beforeCompletion synchronization

172  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Initiating transaction commit

172  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Committing JDBC transaction on Connection [com.mysql.jdbc.Connection@91f005]

172  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Triggering afterCommit synchronization

172  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Triggering afterCompletion synchronization

172  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Releasing JDBC Connection [com.mysql.jdbc.Connection@91f005] after transaction

172  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Using transaction object [org.springframework.jdbc.datasource.DataSourceTransactionManager$DataSourceTransactionObject@1afb0c7]

172  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Creating new transaction with name [orgpeople.OrgPeopleDataManager.initializeCountries]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT

328  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Acquired Connection [com.mysql.jdbc.Connection@2515] for JDBC transaction

328  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Switching JDBC Connection [com.mysql.jdbc.Connection@2515] to manual commit

328  [main] DEBUG org.springframework.jdbc.core.JdbcTemplate  - Executing SQL update [insert into country values (1, 'test country', 'Test Country')]

328  [main] DEBUG org.springframework.jdbc.core.JdbcTemplate  - SQL update affected 1 rows

328  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Triggering beforeCompletion synchronization

328  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Initiating transaction rollback

328  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Rolling back JDBC transaction on Connection [com.mysql.jdbc.Connection@2515]

609  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Triggering afterCompletion synchronization

609  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Releasing JDBC Connection [com.mysql.jdbc.Connection@2515] after transaction

 

 

Case Study

 

Try the same as above but the exception will be in the TestModel

 

TestModel

public class TestModelImpl implements TestModel {

   private OrgPeopleDataManager orgPeopleDataManager;

 

   public void initializeCountries() {

       orgPeopleDataManager.initializeCountries();

       throw new RuntimeException("test");

 

   }

}

 

Expected Results

Database connection will not rollback

 

Actual Results

Database connection did not rollback.

 

 

Case study

 

In this case study we will instead make the testModel’s method transactional.

 

Expected Result

            The transaction will roll back since the TestModel’s method was transactional.

 

Summary of results

 

It actually was transactional

 

Configuration

 

   <bean name="orgPeopleDataManager" class="orgpeople.JdbcOrgPeopleDataManager"/>

 

   <bean id="testModel"

       class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">

       <property name="transactionManager"><ref bean="transactionManager"/></property>

       <property name="target"><ref bean="testModelTarget"/></property>

       <property name="transactionAttributes">

           <props>

               <prop key="*">PROPAGATION_REQUIRED</prop>

           </props>

       </property>

   </bean>

   <bean name="testModelTarget" class="orgcommon.TestModelImpl">

       <property name="orgPeopleDataManager" ref="orgPeopleDataManager"/>

   </bean>

           

 

Log output

 

0    [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Using transaction object [org.springframework.jdbc.datasource.DataSourceTransactionManager$DataSourceTransactionObject@1541147]

0    [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Creating new transaction with name [orgcommon.TestModel.deleteAllCountries]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT

157  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Acquired Connection [com.mysql.jdbc.Connection@18e18a3] for JDBC transaction

157  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Switching JDBC Connection [com.mysql.jdbc.Connection@18e18a3] to manual commit

157  [main] DEBUG org.springframework.jdbc.core.JdbcTemplate  - Executing SQL update [delete from country]

157  [main] DEBUG org.springframework.jdbc.core.JdbcTemplate  - SQL update affected 0 rows

173  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Triggering beforeCommit synchronization

173  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Triggering beforeCompletion synchronization

173  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Initiating transaction commit

173  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Committing JDBC transaction on Connection [com.mysql.jdbc.Connection@18e18a3]

173  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Triggering afterCommit synchronization

173  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Triggering afterCompletion synchronization

173  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Releasing JDBC Connection [com.mysql.jdbc.Connection@18e18a3] after transaction

173  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Using transaction object [org.springframework.jdbc.datasource.DataSourceTransactionManager$DataSourceTransactionObject@18041e0]

173  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Creating new transaction with name [orgcommon.TestModel.initializeCountries]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT

329  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Acquired Connection [com.mysql.jdbc.Connection@278e83] for JDBC transaction

329  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Switching JDBC Connection [com.mysql.jdbc.Connection@278e83] to manual commit

329  [main] DEBUG org.springframework.jdbc.core.JdbcTemplate  - Executing SQL update [insert into country values (1, 'test country', 'Test Country')]

329  [main] DEBUG org.springframework.jdbc.core.JdbcTemplate  - SQL update affected 1 rows

329  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Triggering beforeCompletion synchronization

329  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Initiating transaction rollback

329  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Rolling back JDBC transaction on Connection [com.mysql.jdbc.Connection@278e83]

376  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Triggering afterCompletion synchronization

376  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Releasing JDBC Connection [com.mysql.jdbc.Connection@278e83] after transaction

 

 

 

Case study

 

TestModel is transactional. Data Manager’s method does not support transactions (PROPAGATION_NOT_SUPPORTED).

 

Expected result:

After throwing an exception in the outer method, the inner method should commit and the outer method should rollback.

 

Summery of results:

Performed as expected.

 

 

   <bean name="orgPeopleDataManagerTarget" class="orgpeople.JdbcOrgPeopleDataManager"/>

   <bean name="testModelTarget" class="orgcommon.TestModelImpl">

       <property name="orgPeopleDataManager" ref="orgPeopleDataManager"/>

   </bean>

 

   <bean id="orgPeopleDataManager"

       class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">

       <property name="transactionManager"><ref bean="transactionManager"/></property>

       <property name="target"><ref bean="orgPeopleDataManagerTarget"/></property>

       <property name="transactionAttributes">

           <props>

               <prop key="*">PROPAGATION_NOT_SUPPORTED</prop>

           </props>

       </property>

   </bean>

   <bean id="testModel"

       class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">

       <property name="transactionManager"><ref bean="transactionManager"/></property>

       <property name="target"><ref bean="testModelTarget"/></property>

       <property name="transactionAttributes">

           <props>

               <prop key="*">PROPAGATION_REQUIRED</prop>

           </props>

       </property>

   </bean>  

 

Log of results

 

0    [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Using transaction object [org.springframework.jdbc.datasource.DataSourceTransactionManager$DataSourceTransactionObject@1198ff2]

0    [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Creating new transaction with name [orgcommon.TestModel.deleteAllCountries]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT

157  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Acquired Connection [com.mysql.jdbc.Connection@3a0ab1] for JDBC transaction

157  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Switching JDBC Connection [com.mysql.jdbc.Connection@3a0ab1] to manual commit

157  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Using transaction object [org.springframework.jdbc.datasource.DataSourceTransactionManager$DataSourceTransactionObject@107108e]

157  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Suspending current transaction

157  [main] DEBUG org.springframework.jdbc.core.JdbcTemplate  - Executing SQL update [delete from country]

376  [main] DEBUG org.springframework.jdbc.core.JdbcTemplate  - SQL update affected 1 rows

376  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Triggering beforeCommit synchronization

376  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Triggering beforeCompletion synchronization

391  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Triggering afterCommit synchronization

391  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Triggering afterCompletion synchronization

391  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Resuming suspended transaction

391  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Triggering beforeCommit synchronization

391  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Triggering beforeCompletion synchronization

391  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Initiating transaction commit

391  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Committing JDBC transaction on Connection [com.mysql.jdbc.Connection@3a0ab1]

391  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Triggering afterCommit synchronization

391  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Triggering afterCompletion synchronization

391  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Releasing JDBC Connection [com.mysql.jdbc.Connection@3a0ab1] after transaction

391  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Using transaction object [org.springframework.jdbc.datasource.DataSourceTransactionManager$DataSourceTransactionObject@166f9b9]

391  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Creating new transaction with name [orgcommon.TestModel.initializeCountries]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT

547  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Acquired Connection [com.mysql.jdbc.Connection@1fb3211] for JDBC transaction

547  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Switching JDBC Connection [com.mysql.jdbc.Connection@1fb3211] to manual commit

547  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Using transaction object [org.springframework.jdbc.datasource.DataSourceTransactionManager$DataSourceTransactionObject@940b84]

547  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Suspending current transaction

547  [main] DEBUG org.springframework.jdbc.core.JdbcTemplate  - Executing SQL update [insert into country values (1, 'test country', 'Test Country')]

703  [main] DEBUG org.springframework.jdbc.core.JdbcTemplate  - SQL update affected 1 rows

703  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Triggering beforeCommit synchronization

703  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Triggering beforeCompletion synchronization

703  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Triggering afterCommit synchronization

703  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Triggering afterCompletion synchronization

703  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Resuming suspended transaction

703  [main] DEBUG org.springframework.jdbc.core.JdbcTemplate  - Executing SQL update [insert into country values (2, 'test country outside', 'Test Country outside')]

703  [main] DEBUG org.springframework.jdbc.core.JdbcTemplate  - SQL update affected 1 rows

703  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Triggering beforeCompletion synchronization

703  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Initiating transaction rollback

703  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Rolling back JDBC transaction on Connection [com.mysql.jdbc.Connection@1fb3211]

719  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Triggering afterCompletion synchronization

719  [main] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager  - Releasing JDBC Connection [com.mysql.jdbc.Connection@1fb3211] after transaction