The following service fails to rollback persisting the Foo
object if an IllegalStateException
is thrown although I have marked MyServiceImpl
as @Transactional(rollbackFor = IllegalStateException.class)
. I have also tried to mark the upload
method as @Transactional(rollbackFor = IllegalStateException.class)
, still the problem persists and my Database state would be inconsistent if an IllegalStateException
would occur :
@Service
@Transactional
public class MyServiceImpl implements IMyService{
@Autowired
private IFooService fooService;
@Autowired
private IBarService barService;
@Override
@Transactional(rollbackFor = IllegalStateException.class, propagation = Propagation.REQUIRED)
public void upload(Foo foo, Bar bar) throws IllegalStateException{
try{
fooService.addFoo(foo);//foo object is persisted in the DB whether the upload call would succeed or fail (i.e. throws an IllegalStateException)
if(!check(bar))
throw new IllegalStateException("The object bar is not valid");
barService.addBar();
} catch(Exception e){
e.printStackTrace();
}
}
//This method simply validates the input Bar object
private boolean check(Bar bar){
//source code omitted
}
}
@Service
@Transactional
public class FooServiceImpl implements IFooService{
@Autowired
private IFooDao fooDao;
@Override
@Transactional(propagation = Propagation.REQUIRED)
public void addFoo(final Foo foo){
fooDao.addFoo(foo);
}
}
@Service
@Transactional
public class BarServiceImpl implements IBarService{
@Autowired
private IBarDao barDao;
@Override
@Transactional(propagation = Propagation.REQUIRED)
public void addBar(final Bar bar){
barDao.addBar(bar);
}
}
public class Foo implements Serializable{
private int id;
//source code omitted
}
public class Bar implements Serializable{
private int id;
private Foo foo;
//source code omitted
}
My DataSource config :
@Bean(name="dataSource")
public ComboPooledDataSource getDataSource() throws PropertyVetoException{
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass(env.getProperty("db.driverClass"));
dataSource.setJdbcUrl(env.getProperty("db.jdbcUrl"));
dataSource.setUser(env.getProperty("db.user"));
dataSource.setPassword(env.getProperty("db.password"));
dataSource.setMaxPoolSize(50);
dataSource.setMinPoolSize(5);
dataSource.setMaxConnectionAge(1800);
dataSource.setMaxIdleTime(1800);
dataSource.setAutoCommitOnClose(false);
dataSource.setInitialPoolSize(5);
return dataSource;
}
How can I solve this please?
UPDATE : Source code updated and try/catch
clause added.
It took me a while to spot the reason why the rollback fails. Thanks to ben75's answer. In fact, the source code I provided was not really complete. I forgot to add the try/catch
clause within the upload
method. This is what did really prevent the transaction from being rollbacked although the IllegalStateException
is thrown. In addition to that, I don't need to specify the propagation level since it is REQUIRED
by default.