Откат транзакции 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 (репозитория), укажите это или просто позвольте службе позаботиться о транзакции (при условии, что репозиторий не будет напрямую взаимодействовать с клиентом).

Другие вопросы по тегам