文章参考了此博客: https://blog.csdn.net/qq_40594137/article/details/82772545

写这篇文章之前先说明一下:

1. Controller中添加事务管理,是可行的,但是强烈不推荐,因为不符合实际开发场景,还会导致一系列问题

2. 事务请在Service处理,所有的业务逻辑请写在 Service, Service中异常请抛出,慎用 try...catch捕获异常

写这边文章的背景:

公司有个老的项目,springMVC + spring + mybatis,事务是在Service层处理的,但是之前的开发人员把很多业务逻辑写在了 Controller,出现了操作失败仍然将数据写入数据库的bug.....,于是开始研究在 Controller中添加事务管理

Controller中添加事务管理步骤:

1. spring.xml中事务配置不变

2. 在spring-mvc.xml中定义事务配置:

A: 命名空间中 加入约束 不加项目启动会报异常:
             xmlns:tx="http://www.springframework.org/schema/tx"
             http://www.springframework.org/schema/tx      http://www.springframework.org/schema/tx/spring-tx-4.0.xsd

         B:  定义事务注解解析  <tx:annotation-driven transaction-manager="transactionManager" />

3. 在需要控制事务的Controller 类或者方法上使用 @Transactional(rollbackFor = {Exception.class}) ,当出现异常回滚

需要注意的是:  Controller层只支持 @Transactional 注解式事务!

关于为什么要在spring-mvc.xml中添加 <tx:annotation-driven transaction-manager="transactionManager" />  的说明:

错误的方式----通过修改spring.xml中的配置来实现在controller中控制事务会发现事务无效,如下:

<aop:config>  
    <aop:advisor advice-ref="txAdvice" pointcut="execution(* net.*.controller.*.*(..))"/></aop:config> 

原因如下:  spring容器和spring-mvc是父子容器。在服务器启动时,会先加载web.xml配置文件 ==> 再加载spring配置文件 ==> 再回到web.xml【加载监听器;加载过滤器;加载前端控制器】==>再加载springMVC配置文件,在Spring配置文件中,我们扫描注册的是service实现类,就算扫描注册了controller 也会在后面加载SpringMVC配置文件[扫描注册controller]覆盖掉,所以想要在controller中实现事务管理,仅在spring配置文件配置<tx:annotation-driven>或<aop:config>是没有效果的,必须将事务配置定义在Spring MVC的应用上下文(spring-mvc.xml)中。在spring-framework-reference.pdf文档中说明了: <tx:annoation-driven/>只会查找和它在相同的应用上下文件中定义的bean上面的@Transactional注解

关于 @Transactional 注解的一些说明:

有篇博客写的很好,我就直接链接了 https://www.jianshu.com/p/befc2d73e487

关于@Transaction 事务不起作用的总结:

@Transaction不起作用的情况:1.静态(static )方法

2.(private)私有化方法

3.当本类的使用@Transactional的方法被本类的其它没有开启事务的方法调用时,不会开启事务。

使用@Transactional的方法被其它类调用时,按照正常的事务传播行为规则开启事务

4.未开启注解解析: 配置文件必须加<tx:annotation-driven />,否则不解析@Transactional

5.异常被try{}catch(){}捕捉到了,有异常就不会回滚。

6. 数据库引擎要支持事务: 如果是mysql,注意表要使用支持事务的引擎,比如innodb,如果是myisam,事务是不起作用的

项目中问题的最终处理:

由于 Controller 层中异常不能直接抛到用户,对异常进行了try{}catch(){},导致事务回滚失效,无法通过在 Controller 层添加事务管理来实现事务功能,

所以只能有用以下方式来处理:

1. 将业务逻辑代码移到 service 来处理 : 推荐方法

2. 如果业务逻辑复杂,在维护的时候无法保证逻辑正确的情况下,只有手动编写事务代码来实现回滚了,具体代码如下:(不推荐)

//在每个controller中注入transactionManager
@Resource
private PlatformTransactionManager transactionManager; @PostMapping(value = "setCode")
@ResponseBody
public void setCode(Invoice invoice, InvoiceAddress invoiceAddress,String token,String orderIDs,
Integer pid,HttpServletResponse response){ DefaultTransactionDefinition defaultTransactionDefinition = new DefaultTransactionDefinition();
defaultTransactionDefinition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
TransactionStatus status = transactionManager.getTransaction(defaultTransactionDefinition); try {
invoiceService.insert(token,pid,invoice);
int iID= invoice.getId();
String substring = orderIDs.substring(0, orderIDs.length()-1);
String[] split = substring.split(",");
for (String string2 : split) {
bOrderService.updateIStatus("1",string2);
}
invoiceOrderService.insert(iID,substring);
if(Integer.parseInt(invoice.getiType())==1){
invoiceAddressService.insert(iID,invoiceAddress);
} System.out.println("======制造一个运行时异常aa======");
System.out.println("运行时异常:"+100/0); //没有异常便手动提交事务
transactionManager.commit(status);
printJson(response,result(200,"ok"));
}catch (Exception e){
//有异常便回滚事务
transactionManager.rollback(status);
e.printStackTrace();
printJson(response,result(500,"false"));
} }

 

  

在Controller中添加事务管理的更多相关文章

  1. Spring中的事务管理

    事务简介: 事务管理是企业级应用程序开发中必不可少的技术,用来确保数据的完整性和一致性 事务就是一系列的动作,它们被当作一个单独的工作单元.这些动作要么全部完成,要么全部不起作用 事务的四个关键属性( ...

  2. ASP.NET MVC 学习4、Controller中添加SearchIndex页面,实现简单的查询功能

    参考:http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-mvc4/examining-the-edit-method ...

  3. Spring中的事务管理详解

    在这里主要介绍Spring对事务管理的一些理论知识,实战方面参考上一篇博文: http://www.cnblogs.com/longshiyVip/p/5061547.html 1. 事务简介: 事务 ...

  4. 代码中添加事务控制 VS(数据库存储过程+事务) 保证数据的完整性与一致性

    做人事档案的系统考虑到数据的安全性与一致性,毕竟是要对外上线.真正投入使用的项目,数据库的可靠性与安全性上我们开发人员要考虑的就很多了,记得做机房收费系统时注册新卡是自己为了简单,写成了一个存储过程( ...

  5. Spring框架学习笔记(10)——Spring中的事务管理

    什么是事务 举例:A给B转500,两个动作,A的账户少500,B的账户多500 事务就是一系列的动作, 它们被当做一个单独的工作单元. 这些动作要么全部完成, 要么全部不起作用 一.注解添加事务管理方 ...

  6. spring将service添加事务管理,在applicationContext.xml文件中的设置

    在applicationContext.xml文件中的设置为: <beans> <bean id="sessionFactory" class="org ...

  7. Spring Boot中的事务管理

    原文  http://blog.didispace.com/springboottransactional/ 什么是事务? 我们在开发企业应用时,对于业务人员的一个操作实际是对数据读写的多步操作的结合 ...

  8. 使用sftp操作文件并添加事务管理

    本文主要针对文件操作的事务管理,即写文件和删除文件并且能保证事务的一致性,可与数据库联合使用,比如需要在服务器存文件,相应的记录存放在数据库,那么数据库的记录和服务器的文件数一定是要一一对应的,该部分 ...

  9. Spring Boot 中的事务管理

    希望能在发生异常的时候被回退,这时候就可以使用事务让它实现回退,做法非常简单,我们只需要在test函数上添加@Transactional注解即可. 使用@Transactional注解来声明一个函数需 ...

随机推荐

  1. mac node配置path

    一.查看node安装路径 whitch node 二.打开配置文件 vi ./.bash_profile 三.添加一行PATH(按i进入insert才能编辑) export NODE_HOME=&qu ...

  2. matlab学习笔记13_2匿名函数

    一起来学matlab-matlab学习笔记13函数 13_2 匿名函数 觉得有用的话,欢迎一起讨论相互学习~Follow Me 参考文献 https://ww2.mathworks.cn/help/m ...

  3. sql 在查询到的语句基础上添加行号

    正常查询语句: SELECT TagName FROM ps_status a WHERE a.TagName LIKE "DTmk_zybf%1bxxjcqh.PV" 查询结果: ...

  4. python对不同类型文件(doc,txt,pdf)的字符查找

    python对不同类型文件的字符查找 TXT文件: def txt_handler(self, f_name, find_str): """ 处理txt文件 :param ...

  5. 微信小程序框架 同时兼容QQ小程序

    最近一直在开发微信小程序,经过几个版本的迭代开发,代码终于能够达到框架级别,动态配置.除了界面有些寒酸以外,功能上还是挺完备的. 主要有以下特点 1.整个程序所需url地址均在api.js中定义,环境 ...

  6. 转:webpack代码压缩优化

    压缩代码 18 天前30前端开发 压缩 JavaScript 修改 JavaScript 压缩处理器 其他压缩 JavaScript 的方法 加快 JavaScript 执行速度 作用域提升 预执行 ...

  7. LODOP打印图片水平居中

    其他居中,查看本博客相关博文:LODOP中打印项水平居中简短问答.图片也属于超文本打印项,因此如果想把图片居中,也需要图片本身内容相对于图片打印项宽度居中,然后再设置打印项居中.如图,同一张图片,都设 ...

  8. 1-3docker commit定制镜像

    以定制⼀个 Web 服务器为例⼦ 1.commit定制镜像 docker pull nginx:1.17   运行容器 --name:容器名字 -d:后台 -p本地端口:容器内端口 docker ru ...

  9. Win10 专业版 Hyper-V 主机计算服务无法启动

    Windows 10升级1809版本后,发现Hyper-V不能用了,管理器里是一片空白,看服务Hyper-V 主机计算服务没有启动,手动启动的话失败,报错,代码1053. 自己尝试修复,也百度了很久, ...

  10. 聚焦JavaScript面向对象的思想

    面向对象是一种软件开发方法,是一种对现实世界理解和抽象的方法,是计算机编程技术发展到一定阶段后的产物.随着时代的发展,计算机被用于解决越来越复杂的问题.一切事物皆对象,通过面向对象的方式,将现实世界的 ...