@Transactional没有回滚

时间:2015-11-30 13:05:18

标签: java spring jpa transactions

@Transactional方法调用到另一2层的方法,其也存在于@Transactional的方法,但同时被调用的方法的一个得到例外它的事务应该被回滚,其不会发生

-----The Main Transactional method-------------
@Transactional(propagation = Propagation.REQUIRES_NEW,rollbackFor = RestException.class)
    public BaseDto createFPSAndUser(FpsStoreDto fpsStoreDto){

        log.info("<--Starts FPSStoreService .createFPSAndUser-->"+fpsStoreDto);
        BaseDto baseDto = new BaseDto();
        try {
            UserDetailDto  userDetailDto = fpsStoreDto.getUserDetailDto();
            userDetailDto.setCreatedBy(fpsStoreDto.getCreatedBy());
            baseDto = createFPSStore(fpsStoreDto);
            if(baseDto.getStatusCode() != 0){
                throw new RestException(ErrorCodeDescription.getDescription(baseDto.getStatusCode()));

            }
            userDetailDto.setFpsStore(null);
            baseDto = userDetailService.createUserDetail(userDetailDto);
            if(baseDto.getStatusCode() != 0){
                throw new RestException(ErrorCodeDescription.getDescription(baseDto.getStatusCode()));
            }
            FPSStore fpsStore =  fpsStoreRepository.findByCode(fpsStoreDto.getCode());
            UserDetail userDetail = userDetailRepository.findByUserId(userDetailDto.getUserId());
            userDetail.setFpsStore(fpsStore);
            userDetailRepository.save(userDetail);
            baseDto.setStatusCode(0);
        } catch(RestException restException){
            log.info("RestException -:", restException);
            restException.printStackTrace();
            baseDto.setStatusCode(baseDto.getStatusCode());
        } catch (Exception exception) {
            log.info("Exception -:",exception);
            exception.printStackTrace();
            baseDto.setStatusCode(ErrorCodeDescription.ERROR_GENERIC.getErrorCode());
        }
        log.info("<--Ends FPSStoreService .createFPSAndUser-->"+baseDto);
        return baseDto;
    }

------------------Called method 1st-----------

@Transactional(propagation = Propagation.REQUIRED)
    public BaseDto createFPSStore(FpsStoreDto fpsStoreDto) {
    _________________________
    __________________________
    ________________________
 return baseDto;

}

------------------------2nd Transactional method-----
@Transactional(propagation = Propagation.REQUIRED)
    public BaseDto createUserDetail(UserDetailDto userDetaildto) {
_______________
_______________
_______________
return baseDto
}

3 个答案:

答案 0 :(得分:2)

您已设置rollbackFor=RestException.class,但您的代码会捕获该异常并且不会重新抛出它。从Spring的角度来看,RestException从未被方法抛出,并且没有理由回滚事务。

如果要进行回滚,则需要在catch块的末尾执行throw restException;

答案 1 :(得分:1)

你告诉Spring只在

时回滚事务
rollbackFor = RestException.class

但如果你抓住了例外

catch(RestException restException){

Spring永远不会注意到抛出异常。您需要移除捕获阻塞(两者都有)您可以在捕获结束时抛出异常

    catch(RestException restException){
        log.info("RestException -:", restException);
        restException.printStackTrace();
        baseDto.setStatusCode(baseDto.getStatusCode());
        throw restException;
    }

答案 2 :(得分:0)

@Transactional告诉容器(spring)处理带注释的方法调用的事务管理。

  • 这是使用代理完成的,请参阅understanding aop proxies,这意味着:
    • 注释仅适用于带注释对象的外部调用
    • 只有方法边界之外抛出的异常才会被容器
    • 处理

`

  • 每个带注释的方法都有own transaction logical context,这意味着:
    • 即使您的main方法具有参数rollbackFor=RestException.class 内部人员不会继承配置,并且在抛出休息异常时不会触发回滚
    • 如果内部方法由于在执行期间抛出异常而触发回滚,即使调用者捕获到异常,事务也将回滚,每次对数据库的后续访问都将导致{ {1}}