项目实战--@Transactional 的使用

Posted liaowenhui

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了项目实战--@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后,一但出现错误,就不会执行保存操作(事务的原子性)。

以上是关于项目实战--@Transactional 的使用的主要内容,如果未能解决你的问题,请参考以下文章

This method isn't transactional

JAVAEE——SSH项目实战06:统计信息管理Spring注解开发和EasyUI

如何在 Spring Boot 中使用 @Transactional 注解

一口气说出 6种@Transactional注解的失效场景

一口气说出 6种,@Transactional注解的失效场景

springboot项目中,@transactional 无效