The tutorial on Spring declarative transaction explains how to declare transactions in the xml using the tx namespace. The same namespace also provides an element called <tx:annotation-driven> which can be used be define transactions using annotation. The Transaction Manager can be specified using the transaction-manager attribute, or if there is a bean names transactionManager then it will be used by default. The annotation-driven element specifies that all beans in the application context should be checked for the @Transactional annotation. The annotation can be set at class or method level. The transaction attributes can be specified along with the @Transactional annotation.
Sample Program Overview
The sample program demonstrates spring declarative transactions using annotations. Consider a banking system where amount is transferrred from one account to another account. Money is debited from the first account and credited to the second account. If a problem occurs then the transaction is rolled back. So in case, the amount is debited from the first account and before being credited to the second account, an error occurs then the transaction is rolled back and the money is credited back to the first account.
We will create the Account class with members as number and balance.
We will create the AccountDao class with database access methods .
We will create the AccountService class with members as accountDao.
We will create the DbUtil class with members as dataSource.
We will also create the spring-config.xml .
Finally, we will test our setup using TestSpringProgrammaticTransactions class which will load Spring context and get a reference to AccountService class. We will create two accounts and transfer money from one account to another.
Create the Account (see sample code below). This class represents a bank account.
Create members number and balance (see lines 5-6 below)
Create accessor methods for number and balance (see lines 18-32 below).
Create the debit() method to remove money from the account (see lines 34-36 below).
Create the credit() method to add money to the account (see lines 38-40 below).
Create the AccountDao (see sample code below). This represents the
Data Access Layer
through which data will be stored and retrieved from the database.
Note that AccountDao extends from JdbcDaoSupport (see line 10 below). This class uses JDBC based approach to interact with the database. (See
Spring JdbcDaoSupport Trail
for further details).
Create the insert() method to add a new Account (see lines 13-20 below).
Create the update() method to update balance in aa Account (see lines 22-30 below).
Create the select() method to fetch an Account from database (see lines 32-36 below).
Create the AccountRowMapper class to map JDBC
to Account class.
Create the AccountService (see sample code below).
Transactions are supported for all methods defined in this class (see line 6 below).
Create members accountDao(see line 9 below)
Create accessor methods for accountDao (see lines 11-17 below).
Create the create() method to create a new account (see lines 19-21 below).
Create transferFunds() method (see lines 23-29 below). It is used to successfully transfer funds from one account to another.
Note that the
annotation is used to qualify the transferFunds() method (see line 22 below) which tells Spring that this method should be executed within the scope of a transaction.
Also create transferFundsException() method (see lines 32-40 below). It throws an Exception to simulate an error during fund transfer.
Note that the
annotation is used to qualify the transferFundsException() method (see line 31 below) to tell Spring that this method should be executed within the scope of a transaction. In particular, note that the transaction is rolled back with any exception is thrown using the
attribute of the annotation.
The transaction management is done declaratively using annotations and there is no logic in any of the methods of this class to handle transactions programmatically which demonstrates ease of use of declarative transaction management. This is a very important benefit of using declarative transactions where-in the business logic code need not be polluted with transaction handling related details.
Create the DbUtil (see sample code below). This class used only to create the necessary PERSON table in the database.
Create members dataSource (see line 11 below)
Create accessor methods for dataSource (see lines 13-19 below).
Create the initialize method and execute the ‘CREATE TABLE’ statement to create the PERSON table (see lines 21-32)
Create the spring-config.xml file (see below).
The dependency injection chart for the spring-config is as follows:
The key point to notice here is that the transaction is declaratively managed using annotations via the
tag (see line 30 below). This indicates to Spring that transactions are managed using annotations (e.g
The transaction manager is defined using
class (see lines 32-35 below).
The database parameters defined for dataSource bean (see lines 37-43 below) correspond to the HyperSQL in-memory database.
We also declare the dbUtil bean which initializes the database by creating the ACCOUNT table with NUMBER and BALANCE columns (see lines 45-49 below).
Finally, we need a java program to test our setup.This is done by TestSpringDeclarativeTransactionsAnnotation (see source code below).
We need to tell Spring framework to use the ‘spring-config.xml’ to load our beans (see line 13 below).
We get the reference to AccountService class through Spring using the bean name ‘accountService’ (see line 14 below).
Create two new accounts with account numbers ‘ACC01’ and ‘ACC02’ (see lines 17-24 below).
Transfer 50 dollars from account ‘ACC01’ to account ‘ACC02’ using accountService.transferFunds() method. (see lines 28-33 below). This demonstrates the scenario where amount is successfully transferred from one account to another.
Again transfer 10 dollars from account ‘ACC01’ to account ‘ACC02’ using accountService.transferFundsException() method. (see lines 38-49 below). In this case an exception occurs during fund transfer and the entire operations fails. Note that the balance amounts in accounts remains unaltered. This demonstrates the usage of declarative transactions using annotations to rollback an operation when an error occurs.
This sample program has been packaged as a jar installer which will copy the source code (along with all necessary dependencies) on your machine and automatically run the program for you as shown in the steps below. To run the sample program, you only need Java Runtime Environment (JRE) on your machine and nothing else.
(Alternatively you can go the folder containing the springdeclarativetransactionsannotation-installer.jar and execute the jar using
java -jar springdeclarativetransactionsannotation-installer.jar
This source code for this program is downloaded in the folder specified by you (say, C:\Temp) as an eclipse project called
. All the required libraries have also been downloaded and placed in the same location. You can open this project from Eclipe IDE and directly browse the source code. See below for details of the project structure.