項目實戰--@Transactional 的使用


@Transactional 介紹  

  Spring 事務管理分為編碼式和聲明式的兩種方式,編程式事務指的是通過編碼方式實現事務;聲明式事務基於 AOP,將具體業務邏輯與事務處理解耦。@Transactional屬於聲明式事務中(兩種)的一種,另一種是通過在配置文件(xml)中做相關的事務規則聲明。我這里就不解釋@Transactional注解管理事務的實現步驟了,直接用項目實戰的例子說明為什么要用到@Transactional。

需求說明

  公司項目中的合同表的信息是通過第三方接口傳數據,我需要寫一個合同數據的保存接口,合同表中有一個是合同主表,另一個是合同明細表,明細表中冗余了合同主表的id。對於數據的保存肯定得保證完整性,不能有遺漏,必須全部保存,如果保存的過程中有報錯就不能執行保存操作,這時@Transactional就起到作用了,它能夠保證合同信息及其明細信息完整的保存。

@Override
@Transactional(transactionManager = "userDataSourceTxManager")
public
Long addSingleContractInfo(AddContractInfoReqDto addContractInfoReqDto) { if(null==addContractInfoReqDto){ throw new BizException(ExampleExceptionCode.REQ_PARAM_NON_NULL.getMsg()); } //保存合同主表信息 ContractEo contractEo = ContractEo.newInstance(); DtoHelper.dto2Eo(addContractInfoReqDto,contractEo); contractEo.setUpdateTime(addContractInfoReqDto.getUpdateDate()); contractDas.insert(contractEo); //保存合同商品詳情信息 List<ContractItemDetailReqDto> itemDetailReqDtos = addContractInfoReqDto.getItemDetailReqDtoList(); itemDetailReqDtos.stream().forEach(dto->{
ContractItemDetailEo contractItemDetailEo
= ContractItemDetailEo.newInstance(); DtoHelper.dto2Eo(dto,contractItemDetailEo); //合同商品明細表中冗余主表id contractItemDetailEo.setUsContractId(contractEo.getId()); contractItemDetailDas.insert(contractItemDetailEo); }); return contractEo.getId();
}

注意事項

  第二條紅色標注的新建合同明細實體類代碼必須寫在里面,每次保存后都新建一個新的合同明細實體,如果寫在外面的話就會報錯

java.sql.SQLIntegrityConstraintViolationException: Duplicate entry '0' for key 'PRIMARY'.實體主鍵id重復了,這時如果你沒在方法上加上@Transactional注解,雖然出現報錯了,但是數據庫還是會執行保存操作,只存入合同明細集合的第一條數據(后面的主鍵id重復了,不保存),造成數據保存不完整,加了@Transactional后,一但出現錯誤,就不會執行保存操作(事務的原子性)。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM