pratim_b
pratim_b

Reputation: 1200

Why DataSourceTransactionManage does not roll back while HibernateTransactionManager does?

<bean id="transactionManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
        lazy-init="true">
        <property name="dataSource" ref="dataSource" />
    </bean>

While building an app using spring and hibernate , if I use DataSourceTransactionManager, then on exception , it does not roll back. Seems like it uses auto-comit in different session. However , if I change the transaction manager to org.springframework.orm.hibernate3.HibernateTransactionManager, the roll back works as expected. Or is it that if we use hibernate , then we need to use HibernateTransactionManager?

N.b: My service annotated with @Transactional(rollbackFor = { Throwable.class} )

Upvotes: 2

Views: 850

Answers (2)

Vlad Mihalcea
Vlad Mihalcea

Reputation: 153960

According to Spring documentation:

PlatformTransactionManager implementations normally require knowledge of the environment in which they work: JDBC, JTA, Hibernate, and so on.

If you use JTA in a Java EE container then you use a container DataSource, obtained through JNDI, in conjunction with Spring’s JtaTransactionManager.

You can also use Hibernate local transactions easily...

In this case, you need to define a Hibernate LocalSessionFactoryBean, which your application code will use to obtain Hibernate Session instances ... in this case is of the HibernateTransactionManager type.

In the same way as the DataSourceTransactionManager needs a reference to the DataSource, the HibernateTransactionManager needs a reference to the SessionFactory.

Although:

DataSourceTransactionManager will binds a JDBC Connection from the specified DataSource to the current thread, potentially allowing for one thread-bound Connection per DataSource.

the Session won't be bound to the current transaction and you need both for local transactions.

This is what hibernate or JPA specific TM would do for you. They will associate the persistence context and one connection per transaction per thread.

If you choose JTA transactions than an external TM will coordinate transactions. DB connections will be released aggressively after each statement, which is fine as long as the external TM will always return the same connection to the same thread during a global transaction life.

Upvotes: 0

M. Deinum
M. Deinum

Reputation: 124909

When working with plain hibernate the following is needed to manage transactions

Session s = sessionfactory.openSession();
Transaction tx = null;
try {
tx = s.beginTransaction();
// Your data manipulation here
tx.commit();
} catch (Exception e) {
if (tx != null) { tx.rollback();}
} finally {
s.close();
}

This is also what the HibernateTransactionManager does (open a session if needed, start transaction, afterwards commit/rollback).

Now what you are trying to do is the following (which is kind-of similair to the DataSourceTransactionManager, that operates on the `DataSource instead of the session.)

Session s = sessionfactory.openSession();
Connection conn = null;
try {
    conn = s.connection();
    // Your data manipulation here
    conn.commit();
} catch (Exception e) {
    if (conn != null) { 
        try {
            conn.rollback();
        catch (IOExceptin) {}
    }
} finally {
    s.close();
}

Which isn't going to work as the actual transactional unit, the session, is never getting informed of the commit or rollback. So in the worst case, depending in your flush-mode, everything (or partially) gets committed.

In short always use the transaction manager which fits your technology.

When using plain hibernate use the HibernateTransactionManager, when using JPA use the JpaTransactionManager, don't use the DataSourceTransactionManager in those cases as that is usable only in situations where only plain JDBC is used.

The DataSourceTransactionManager clearly states that it operates on the DataSource and underlying connection. Whereas when one uses Hibernate the transaction is controlled by the hibernate Session, this is the level where the HibernateTransactionManager operates on. For JPA this is the EntityManager and this is what the JpaTransactionManager recognizes.

Upvotes: 4

Related Questions