Hibernate + Spring事务回滚不起作用

时间:2012-10-17 03:07:58

标签: spring hibernate transactions rollback

当服务提供一个配置为回滚的异常(rollbackfor)时,此回滚不起作用。

服务类:

@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("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");
}

}

有一种情况是回滚有效。为此,我需要更改BookServiceImpl,删除readOnly = true并删除“transactionTest”方法的“@Transactional(readOnly = false)”。但出于安全考虑,我希望对所有类使用readOnly = true并指定使用readOnly = false的方法

1 个答案:

答案 0 :(得分:2)

目前整个BookServiceImpl交易配置为@Transactional(propagation = Propagation.REQUIRED, rollbackFor = { BusinessException.class }, readOnly = true)

transactionTest覆盖注释为@Transactional(readOnly = false),当您使用类覆盖注释时,方法整个注释已更新而不是仅指定属性。

而不是这个,你应该在下面作为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");
          }
     }
}

并且如果你想在DAO(存储库)级别上进行相同类型的事务,那么指定它或者让服务来处理事务(假设存储库不会直接与客户端连接)。