spring Transactional annotation

A step by step explanation for Transactional Annotation.

Spring creates proxies for classes that declare @Transactional on the class itself or on members. The proxy is mostly invisible at runtime. It provides a way for Spring to inject behaviors before, after, or around method calls into the object being proxied. Transaction management is just one example of the behaviors that can be hooked in. Security checks are another. And you can provide your own, too, for things like logging. So when you annotate a method with @Transactional, Spring dynamically creates a proxy that implements the same interface(s) as the class you’re annotating. And when clients make calls into your object, the calls are intercepted and the behaviors injected via the proxy mechanism.

When Spring loads your bean definitions, and has been configured to look for @Transactional annotations, it will create these proxy objects around your actual bean. These proxy objects are instances of classes that are auto-generated at runtime. The default behaviour of these proxy objects when a method is invoked is just to invoke the same method on the “target” bean (i.e. your bean).

However, the proxies can also be supplied with interceptors, and when present these interceptors will be invoked by the proxy before it invokes your target bean’s method. For target beans annotated with @Transactional, Spring will create a TransactionInterceptor, and pass it to the generated proxy object. So when you call the method from client code, you’re calling the method on the proxy object, which first invokes the TransactionInterceptor (which begins a transaction), which in turn invokes the method on your target bean. When the invocation finishes, the TransactionInterceptor commits/rolls back the transaction. It’s transparent to the client code.

only external method calls will be under Transaction and not the self-invocation methods. 

if your bean invokes one of its own methods, then it will not be doing so via the proxy. Remember, Spring wraps your bean in the proxy, your bean has no knowledge of it. Only calls from “outside” your bean go through the proxy.

Difference between hibernate/db/spring transaction

Hibernate deals with database specific transactions, whereas spring provides a general transaction management service. @Transactional is a nice way of configuring transaction management behaviour.

The long story:

Transactions

Transactions are basically units of work (ie changes to something) that are managed as a single operation that can be either committed or rolled back. There are lots of different types of transactions in the java world – database, messaging systems like JMS, inter application transactions (for those who are not faint of heart) or anything else that may need to be included in a transaction. In the Java standard transactions are managed using the Java Transaction API which sets the rules for how to participate in a transaction.

Database

For a db transaction, it is bind to the connection get.

try{
  con.setAutoCommit(false);
  ....
  con.commit();
}catch(ex e){
  con.rollback();
}

Hibernate

Hibernate is an ORM for abstracting database components to Java objects, so its transactions are specifically related to changes made within a database. A transaction may be made up of one or many writes to various database tables that are all committed once the operation is completed. Rolling back the transaction, eg f there are any errors during the operation, allows all the changes to be undone.

Spring

At its lowest level Spring is a application framework for managing configuration and dependencies between objects. In addition it also provides an interface for managing higher level services that are used in modern applications such as databases, messaging services, MVC frameworks and transactions.

Spring is designed to be used as an all-encompassing master of objects and services within your application, so its concept of a transaction is at a higher level than the database specific transactions that hibernate concerns itself with. Spring Transactions are designed to give you fine grained control of all your transactional resources while abstracting away the often messy coding required to co-ordinate the transactions.

@Transactional

Spring provides a few different methods for using transactions – among others there xml based aspects, coding to the API and annotation based declarative transactions. The annotation based transactions are handy because you dont need to add the transaction management boilerplate code to your app (even using PlatformTransactionManager via the API has quite a bit of coding overhead).

So basically what happens with @Transactional is that at runtime spring scans your code base for @Transactional classes and methods and wraps them up in the transaction specific management code, based on what you have configured via the annotation. So a method like this:

@Transactional(propagation = REQUIRES_NEW, rollbackFor = {Exception.class})
public void saveAndSendMessage(Foo foo) throws Exception {
    dbManager.save(foo);
    Bar bar = transform(foo);
    jmsSystem.send(bar);
}  

can have spring set up a new transaction for the database and jms system, and co-ordinate them without needing to add all the specific tx management code automagically.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s