博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
service层@Transactional事务控制使用以及注意
阅读量:4042 次
发布时间:2019-05-24

本文共 2264 字,大约阅读时间需要 7 分钟。

 

@Service@Transactionalpublic class CeshiService {    @Autowired    LoginFeignClient loginFeignClient;    @Transactional(rollbackFor = Exception.class)    public void test(){        User user=null;        //try {            log.info("ceshi transactional is 1");            user=loginFeignClient.test1().getData();            throw  new RuntimeException();            //log.info("ceshi transactional is 2");           // loginFeignClient.test();       // }catch (Exception e){        //    throw new Exception(e.getLocalizedMessage());       // }    }}

上述就是一个事务的service,当获取到throw的exception时执行rollback;

 

1.service中是通过feign调用远程服务时,上述写法是无法回滚的,只有repository在本地代码处理才可以,因为db提供了回滚处理。

2.如果是feign远程调用,又想使用事务,则需要进行逆服务处理,需要获取异常时,手动调用逆服务处理

3.非事务声明方法调用事务声明方法,则事务失效。使用了@Transactional的方法,对同一个类里面的方法调用, @Transactional无效。比如有一个类Test,它的一个方法A,A再调用Test本类的方法B(不管B是否public还是private),但A没有声明注解事务,而B有。则外部调用A之后,B的事务是不会起作用的。(经常在这里出错)

针对这种情况,进行了实例测试:

@Service@Slf4jpublic class TransTestService {    @Autowired    QueueAppointRecordMapper  queueAppointRecordMapper ;    public void noTrans(){        QueueAppointRecordVo recordVo = new QueueAppointRecordVo();        recordVo.setId(6549928413648389141L);        List
list1 = queueAppointRecordMapper.getAppointRecordById(recordVo); log.info("record status1:{}", list1.get(0).getStatus()); QueueAppointRecordVo vo = new QueueAppointRecordVo() ; vo.setId(6549928413648389141L); vo.setStatus("R07"); queueAppointRecordMapper.updateStatus(vo) ; log.info("noTrans,status:R07"); trans(); } @Transactional public void trans(){ QueueAppointRecordVo vo = new QueueAppointRecordVo() ; vo.setId(6549928413648389141L); vo.setStatus("R09"); queueAppointRecordMapper.updateStatus(vo) ; log.info("trans,status:R09"); throw new RuntimeException() ; }}

没有@Transactional标签的方法notrans调用有@Transactional的方法trans方法,

这条记录原始状态R01,经过程序后依次变更为R07  R09,虽然trans事务方法遇到了runtimeException,最后查数据库的状态也是R09。也就说明trans方法的事务是没有起作用的。

4.一个service中声明事务方法,调用了另外一个service中的声明事务方法,则被调用的方法事务也还起作用,事务不太建议放到2个见service中。下面的例子,下面的事务是起作用的,跟上面第3条写的注意区分:

同一工程内,controller中调用第一个service声明了Transactional,service中再调用其他service中非声明的事务,如果遇到RunTimeException则还是事务回滚的,但是尽量使用事务的方法,都加上Transactional声明

 

 

你可能感兴趣的文章
VC++ MFC SQL ADO数据库访问技术使用的基本步骤及方法
查看>>
VUE-Vue.js之$refs,父组件访问、修改子组件中 的数据
查看>>
Vue-子组件改变父级组件的信息
查看>>
Python自动化之pytest常用插件
查看>>
Python自动化之pytest框架使用详解
查看>>
【正则表达式】以个人的理解帮助大家认识正则表达式
查看>>
性能调优之iostat命令详解
查看>>
性能调优之iftop命令详解
查看>>
非关系型数据库(nosql)介绍
查看>>
移动端自动化测试-Windows-Android-Appium环境搭建
查看>>
Xpath使用方法
查看>>
移动端自动化测试-Mac-IOS-Appium环境搭建
查看>>
Selenium之前世今生
查看>>
Selenium-WebDriverApi接口详解
查看>>
Selenium-ActionChains Api接口详解
查看>>
Selenium-Switch与SelectApi接口详解
查看>>
Selenium-Css Selector使用方法
查看>>
Linux常用统计命令之wc
查看>>
测试必会之 Linux 三剑客之 sed
查看>>
Socket请求XML客户端程序
查看>>