Reputation: 847
When service thown an exception that is configured to rollback (rollbackfor), this rollback not working.
Service class:
@Service("bookService")
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = { BusinessException.class }, readOnly = true)
public class BookServiceImpl implements BookService {
@Autowired
private BookRepository bookDAO;
@Override
@Transactional(readOnly = false)
public void transactionTest(Book book) throws BusinessException {
try {
bookDAO.test(book);
} catch (DAOException e) {
throw new BusinessException("test rollback - service");
}
}
}
Repository class:
@Repository("bookRepository")
public class BookRepositoryImpl implements BookRepository {
@Autowired
private SessionFactory sessionFactory;
@Transactional(readOnly = false)
@Override
public Book saveOrUpdate(Book book) {
if (book.getId() != null) {
getSession().merge(book);
} else {
getSession().save(book);
}
return book;
}
@Transactional(readOnly = false)
@Override
public void test(Book book) throws DAOException {
saveOrUpdate(book);
System.out.println(book.getTitle() + " inserted!");
throw new DAOException("Test rollback");
}
}
There are one situation that rollback works. To this, I need change BookServiceImpl removing readOnly = true and removing "@Transactional(readOnly = false)" of the "transactionTest" method. But for security reasons I wish use readOnly = true for all class and specify what is method use readOnly = false
Upvotes: 1
Views: 4725
Reputation: 6273
currently for whole BookServiceImpl
transaction configuration is @Transactional(propagation = Propagation.REQUIRED, rollbackFor = { BusinessException.class }, readOnly = true)
and for transactionTest
overridden annotation is @Transactional(readOnly = false)
, when you override annotation with class to method whole annotation updated instead of just specified attribute.
instead of this you should have below as code for BookServiceImpl
@Service("bookService")
@Transactional(readOnly = true)
public class BookServiceImpl implements BookService {
@Autowired
private BookRepository bookDAO;
@Override
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = { BusinessException.class },readOnly = false)
public void transactionTest(Book book) throws BusinessException {
try {
bookDAO.test(book);
} catch (DAOException e) {
throw new BusinessException("test rollback - service");
}
}
}
and further if you want same kind of transaction on DAO (Repository) level then specify it or just let service to take care about transaction (assuming repository are not going to be directly interfaced with client).
Upvotes: 2