Откат транзакции Hibernate + Spring не работает
Когда служба обнаружила исключение, настроенное для отката (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 и удалив "@Transactional(readOnly = false)" метода "actionTest". Но из соображений безопасности я хочу использовать readOnly = true для всех классов и указать, что такое метод readOnly = false
1 ответ
В настоящее время для всего 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 (репозитория), укажите это или просто позвольте службе позаботиться о транзакции (при условии, что репозиторий не будет напрямую взаимодействовать с клиентом).