@Transactional service method, two DAOs implemented from parameterized interface

42 views Asked by At

I'm unable to rollback a transaction in Spring Boot 2.1.4 involving two DAOs (JDBC). The DAOs implement a parameterized interface. The first DAO inserts a record into three tables, and the last DAO inserts a record into one table. I'm forcing the last DAO insert to fail.

Database is DB2.

Some code:

public interface FooDao<T extends Foo> {
    int insert(T foo) throws SQLException;
}

@Repository
public class FooDaoJdbc implements FooDao {
    @Override
    public int insert(Foo foo) throws SQLException {
        insertFoo(foo);
        insertFooDescriptions(foo);
        insertFooActivity(foo);
        return 0;
    }
}

@Repository
public class BazDaoJdbc implements FooDao<Baz>  {
    @Override
    public int insert(Baz baz) throws SQLException {

public interface FooService<T extends Foo> {
    void add(T foo) throws SQLException;
}

@Service
public class BazServiceImpl implements FooService<Baz> {

    private FooDao<Baz> bazDaoJdbc;

    private FooDao<Foo> fooDaoJdbc;

    @Transactional(rollbackFor = Exception.class)
    public void add(Baz baz) throws SQLException {
                fooDaoJdbc.insert(foo);
        bazDaoJdbc.insert(baz);        
        }
}

It sure seems the FooDaoJdbc and BazDaoJdbc are in the same transaction when I debug TransactionAspectSupport, but the rollback seems to ignore FooDaoJdbc. I don't have a record in the "baz" table, but I would expect the three "foo" tables to rollback, too. My eyes are crossed at this point. Do I have a misplaced annotation? Am I making things too "fancy" with generics? Thanks in advance for the help!

1

There are 1 answers

3
TranNgocKhoa On

A @Transactional method only rollback when unchecked exception is thrown. So you have to throw RuntimeException in add method when an exception is thrown.

@Service
public class BazServiceImpl implements FooService<Baz> {

    private FooDao<Baz> bazDaoJdbc;

    private FooDao<Foo> fooDaoJdbc;

@Transactional
    public void add(Baz baz) {
     try {
            fooDaoJdbc.insert(foo);
            bazDaoJdbc.insert(baz);   
        } catch (Exception e) {
         throw new RuntimeException(e.getMessage());
        }     
    }
}

More information: https://www.catalysts.cc/wissenswertes/spring-transactional-rollback-on-checked-exceptions/