Skip to content
This repository was archived by the owner on Oct 13, 2024. It is now read-only.
This repository was archived by the owner on Oct 13, 2024. It is now read-only.

转账场景:转出服务confirm阶段判断金额超出,抛出异常,本地事务回滚了,全局事务没有收到异常,全局事务被成功了 #742

@Hakunata

Description

@Hakunata

转出服务的confirm方法:
`

@Transactional
public UserAccount confirm(TransferEntity entity){
    UserAccount userAccount = accountMapper.selectByIdForUpdate(entity.getId());
    if (userAccount.getAmount().compareTo(new BigDecimal(entity.getMoney().toString())) == -1){
        // *******************************************
        // 这里抛出异常了,全局事务无法感知,prepare阶段是可以的,所以也无法调到后面的cancel,造成成功假象
        // *******************************************
        throw new IllegalArgumentException("Transfer failed,not enough money");
    }
    userAccount.setAmount(userAccount.getAmount().subtract(new BigDecimal(entity.getMoney().toString())));
    userAccount.setFreezedAmount(userAccount.getFreezedAmount().subtract(new BigDecimal(entity.getMoney().toString())));
    accountMapper.updateById(userAccount);
    return userAccount;
}`

全局事务没有收到错误或异常,造成全局事务执行成功的错误结果:
`

@TccStart
public Result transfer(TransferEntity transferEntity){
    String errMsg = "";
    Integer errCode = 0;
    // 调用转出微服务
    try{
        // *******************************************
        // 其实转出服务confirm阶段异常回滚了,但是这里不知道,因为拿到一个错误的结果了
        // *******************************************
        ResponseEntity<UserAccount> outReuslt = alphaClient.getForEntity(getBankAlphaURL(transferEntity),UserAccount.class,transferEntity.getFromId(),transferEntity.getMoney() );
        System.out.println(outReuslt.getBody());
    }catch (Exception e){
        e.printStackTrace();
        throw e;
    }
    // 调用转出微服务
    try{
        // *******************************************
        // 转入服务继续执行,其实转出confirm阶段已经出错回滚了
        // *******************************************
        ResponseEntity<UserAccount> inReuslt = betaClient.getForEntity(getBankBetaURL(transferEntity),UserAccount.class,transferEntity.getToId(),transferEntity.getMoney() );
        System.out.println(inReuslt.getBody());
    }catch (Exception e){
        e.printStackTrace();
        throw e;
    }
    return new Result(errCode,errMsg);
}`

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions