Lets recall transaction processing (Java with Spring) – part 2

So lets get back to the overview of transactions in Java with Spring Framework.

Bean-managed transactions can be:

  • container-managed transactions or declarative transaction management
  • application-managed transactions or programmatic transaction management

Declarative transaction management can be XML-based or annotation-based. A disadvantage of declarative transactions is: when a method is executing, it can be associated either with a single transaction or no transaction at all.

Programmatic transaction management gives more liberty. Take as example this pseudocode from Java EE 6 Tutorial (quite old but makes the point):

begin transaction
...
    update table-a
...
    if (condition-x)
   commit transaction
    else if (condition-y)
   update table-b
   commit transaction
    else
   rollback transaction
   begin transaction
   update table-c
   commit transaction

This fine-grained programmatic dependency of when to commit or rollback can only be achieved without declarative transactions.

Transaction Propagation

Not mentioned so obvious is the fact of what is the DEFAULT propagation in Spring transactions.

  • The default propagation is REQUIRED
Propagation types and their behaviour
PROPAGATION TYPE no current transaction there’s a current transaction
MANDATORY throw exception use current transaction
NEVER don’t create a transaction, run method outside any transaction throw exception
NOT_SUPPORTED don’t create a transaction, run method outside any transaction suspend current transaction, run method outside any transaction
SUPPORTS don’t create a transaction, run method outside any transaction use current transaction
REQUIRED(default) create a new transaction use current transaction
REQUIRES_NEW create a new transaction suspend current transaction, create a new independent transaction
NESTED create a new transaction create a new nested transaction

Table is from ninjalj’s blog.

So lets see what this means in the context of a database connection and what the other propagation types.

And because I never went in too much detail here, I recommend to read Marco Behler’s blog to get the full picture.

Lets recall transaction processing (Java with Spring)

Generics about transactions

I am writing a piece about transactions because the subject of transactions sounds so heavy standalone and also because I recently had to recall all the theory from university about it. And surprise surprise, real life software behaves/looks different than in the theory. So, if you are looking to refresh your knowledge and also get the bullet points to simply solidify knowledge keep reading… (at least the bullet points).

Transaction processing is information processing in computer science that is divided into individual, indivisible operations called transactions. Each transaction must succeed or fail as a complete unit; it can never be only partially complete.”

“Transaction processing is designed to maintain a system’s Integrity in a known, consistent state, by ensuring that interdependent operations on the system are either all completed successfully or all canceled successfully.”  Wikipedia

Only reading the definition of transactions we are remembered of the correct way of using them and what the goal should be:

  • indivisible operations
  • succeed or fail as a complete unit
  •  maintain a system’s integrity

We got this on our agenda so lets turn to the technicalities of it.

A good example, which occurs most in real life software, is the work with databases. Databases should have a build in mechanism to tap into their transactional usage either automatic – it takes care on its own on these – or more “manual” – it is up to the developer to decide when the transaction starts and ends. Find out in the design and requirements phase, which scenario you need. Set the parameter of the database correct:

  • database auto-commit true or false

I want to focus on the database.autoCommit(false) scenario next because we differentiate between actions. On some actions transactions are not necessary.

Just because I have to mention: a reliable transactional system must comply to the ACID criteria to be good (atomicity, consistency, isolation, and durability). When you use a transactional system you just need to know that you can rely on ADIC criteria but you do not need to be concerned with each one of them in depth. However, the way you use transactions could violate one of the criteria. A misbehavior is not when a database will rollback if you throw an Exception when in fact it should only be a warning. Conclusion is:

  • you can rely on the ACID criteria the transactional system complies to*

Spring Framework transaction abstraction

Lets get specific and take Spring as a framework that can help you take control of the database transactional system. Spring is not the actual transactional system but it exposes an interface, that perfectly integrates with different transactional systems and it is called Spring Framework Transaction abstraction.

To get started you need to:

  • define the correct PlatformTransactionManager implementation (usually through dependency injection)
  • use the TransactionStatus interface to control transaction execution and query transaction status

The Spring transactional abstraction offers a lot of flexibility when it comes to controlling the transactional system. The implementation you choose must be a trade off between how tightly coupled you want/need to be to Spring’s transaction infrastructure and the need to use a non-invasive lightweight container which has less impact on application code. In this regard you need to choose between:

  • programmatic transaction management in Spring
  • declarative transaction management in Spring (XML or annotation based approach)

You can check out the differences in more detail in the Spring documentation. And a few words on how to chose between them is mentioned here.

Some general advice when using Spring transactions:

  • You are strongly encouraged to use the declarative approach to rollback, if at all possible. Spring docu
  • When using proxies, you should apply the @Transactional annotation only to methods with public visibility. If you do so on other access modifiers(protected, private or package-visible) methods, no error is raised but the annotated method does not exhibit the configured transactional settings. Spring docu
  • Spring recommends that you only annotate concrete classes (and methods of concrete classes), as opposed to annotating interfaces. Spring docu
  • @Transactional annotation on the method of the same class takes precedence (are more important) over the transactional settings defined at the class level. Spring docu
* of course, unless you need to debug exactly that and find out an enterprise ready system has bugs – bad luck…

To be continued…

Or just skip to a blog post I found recently written by Marco Behler.