項目實戰--@Transactional 的使用

@Transactional 介紹  

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

需求說明

  公司項目中的合同表的信息是經過第三方接口傳數據,我須要寫一個合同數據的保存接口,合同表中有一個是合同主表,另外一個是合同明細表,明細表中冗餘了合同主表的id。對於數據的保存確定得保證完整性,不能有遺漏,必須所有保存,若是保存的過程當中有報錯就不能執行保存操做,這時@Transactional就起到做用了,它可以保證合同信息及其明細信息完整的保存。
sql

@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後,一但出現錯誤,就不會執行保存操做(事務的原子性)。編程

相關文章
相關標籤/搜索