首页 > 解决方案 > 围绕事务服务的 Spring AOP

问题描述

我有 2 张桌子CONTRACTLG_CONTRACT. 每次更新合同时,我都希望将更改存储在LG_CONTRACT.

我的 AOP

    @Around(value = "execution(* id.co.somepackage.cofinjms.service.implement.ConverterImpl.signContract(id.co.somepackage.cofinjms.entity.Contract,net.somepackage.homerselect.contract.v3.ContractFullInfoRequest))")
    public Contract around(ProceedingJoinPoint joinPoint) throws Throwable {
        Contract contract = (Contract) joinPoint.getArgs()[0];
        ContractFullInfoRequest contractFullInfoRequest = (ContractFullInfoRequest) joinPoint.getArgs()[1];
        if (contract != null) {
            javers.commit(contract.getContractNumber(), contract);
        }
        Contract updatedContract = (Contract) joinPoint.proceed();
        if (contract != null) {
            javers.commit(contract.getContractNumber(), updatedContract);
            Set<LgContract> lgContractSet = new HashSet<>();
            Date date = new Date();
            List<Change> changes = javers.findChanges(QueryBuilder.byInstanceId(contract.getContractNumber(), Contract.class).build());
            for (Change change : changes) {
                if (change.getClass().equals(ValueChange.class)) {
                    ValueChange vc = (ValueChange) change;
                    String oldValue = vc.getLeft() == null ? null : vc.getLeft().toString();
                    LgContract lgContract = new LgContract();
                    lgContract.setContract(contract);
                    lgContract.setColumnName(vc.getPropertyName());
                    lgContract.setValueOld(oldValue);
                    lgContract.setValueNew(vc.getRight() != null ? vc.getRight().toString() : null);
                    lgContract.setDtimeCreated(date);
                    lgContract.setSystemEvent(contractFullInfoRequest.getSystemEvent().toString());
                    lgContractSet.add(lgContract);
                }
            }
            updatedContract.setLgContracts(lgContractSet);
        }
        return updatedContract;
    }

服务

@Transactional
    public Contract saveContract(String message) throws ContractNotFoundException {
        ContractFullInfoRequest contractFullInfoRequest = JAXB.unmarshal(new StringReader(message), ContractFullInfoRequest.class);
        Contract contract = contractFullInfoRepository.findOne(contractFullInfoRequest.getData().getContractCode());
        switch (contractFullInfoRequest.getSystemEvent()) {
            case CONTRACT_SIGN_SE:
                contract = converter.signContract(contract, contractFullInfoRequest);
                break;
            case CONTRACT_ACTIVATION_SE:
                if (contract != null)
                    contract = converter.logBslStatusChange(contract, contractFullInfoRequest);
                else
                    contract = converter.activateNewContract(contractFullInfoRequest);
                break;
            case CONTRACT_PAID_OFF_SE:
            case CONTRACT_FINISHING_AUTOMATICALLY_SE:
            case CONTRACT_CANCELLATION_SE:
            case CONTRACT_FER_EXECUTED_SE:
            case PARTIAL_EARLY_REPAYMENT_SE:
                if (contract != null)
                    converter.logBslStatusChange(contract, contractFullInfoRequest);
                else
                    throw new ContractNotFoundException("Contract In MsContract Not Found");
                break;
            case CONTRACT_SERVICE_CHANGE_SE:
                if (contract != null)
                    converter.convertServiceChange(contract, contractFullInfoRequest);
                else
                    throw new ContractNotFoundException("Contract In MsContract Not Found");
                break;
            default:
                throw new NotYetImplementedException();
        }
        return contract;
    }

AOP 的工作原理如下

  1. 获取现有合同(在更新/签署之前)
  2. 提交现有合约
  3. 让 signContract 服务继续并在CONTRACT表中存储更新的合同
  4. 在签署过程发生之前和之后比较合同,然后将更改存储在LG_Contract表中

大多数情况下这是可行的,但是我注意到有些情况下 AOP 能够存储更改,但合同本身没有更新。

这是当一切按预期工作时 LG_CONTRACT 的外观(状态从 S > N > A 更改)

3900742668  bslStatus   S   N   06-MAR-19 10.17.07.967000000 AM CONTRACT_SIGN_SE
3900742668  bslStatus   N   A   07-MAR-19 06.04.24.963000000 PM ContractActivationSE

以及当签名过程未按预期工作时(状态从未在 CONTRACT 表中设置为 N,但 LG_CONTRACT 知道何时将状态设置为 N)

3902643905  bslStatus   S   N   11-JUL-19 11.32.09.400000000 AM CONTRACT_SIGN_SE
3902643905  bslStatus   S   A   12-JUL-19 10.51.00.383000000 AM ContractActivationSE

我不明白为什么有时AOP 能够存储从 S 到 N 的合同状态更改,LG_CONTRACT但它没有反映在CONTRACT表中。

标签: spring-aopspring-transactionsjavers

解决方案


推荐阅读