Spring Data Jpa - Как выполнить откат?

Как выполнить откат в Spring Data JPA для следующего сценария?

Transactional
@Override
public Employee saveEmployee(EmployeeDto dto) {
    // check if EmployeeId and Department Id is present
    Employee employee = this.getByEmployeeId(dto);
    Department department = this.getByDepartmentId(dto);

    Employee employee = convertToEntity(dto, employee, department);
    employee.setEmployees(Arrays.asList(employee));
    department.setEmployees(Arrays.asList(employee));

    try {
        employee = employeeRepository.save(employee); //line-11
    } catch (DataIntegrityViolationException e) {
        throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "ConstraintViolationException", e.getCause());
    } catch (Exception ex) {
        throw new InternalServerException(HttpStatus.INTERNAL_SERVER_ERROR, env.getProperty(IConst.ERROR_DB_EXCEPTION), ex);
    }

    EmployeeEmployeeDepartment r = new EmployeeEmployeeDepartment();
    r.setId(new EmployeeDepartmentPK());
    r.setEmployee(employee);
    r.setDepartment(department);
    r.setEmployee(employee);

    try {
        compositeRepository.save(r); //line-22
    }catch (DataIntegrityViolationException e) {
        throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "ConstraintViolationException", e.getCause());
    } 
    catch (Exception ex) {
        throw new InternalServerException(HttpStatus.INTERNAL_SERVER_ERROR, env.getProperty(IConst.ERROR_DB_EXCEPTION), ex);
    }
    return employee;
}

Как откатить строку-11, если строка-22 не работает?

2 ответа

Используйте "rollbackFor"

@Transactional(rollbackFor = DataIntegrityViolationException.class)

Многократное исключение:

@Transactional(rollbackFor = { ResponseStatusException.class, InternalServerException.class })

1) Если ResponseStatusException а также InternalServerException оба RuntimeExceptions тогда вам не нужно ничего делать, поскольку Spring по умолчанию откатывает всю транзакцию в любом RTE.

2) Просто имейте ввиду, что вызывая save() и в конце концов persist() on entityManager не вызывает какого-либо физического обновления в БД, пока транзакция не будет зафиксирована. Эти методы просто регистрируют сущность в контексте постоянства.

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