我的编程空间,编程开发者的网络收藏夹
学习永远不晚

SSM怎么实现在Controller中添加事务管理

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

SSM怎么实现在Controller中添加事务管理

这篇文章主要介绍“SSM怎么实现在Controller中添加事务管理”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“SSM怎么实现在Controller中添加事务管理”文章能帮助大家解决问题。

SSM在Controller中添加事务管理

本人使用:

  • 集成开发环境:idea

  • 项目管理工具:maven

  • 数据库:oracle

  • 框架:Spring+SpringMVC+myBatis

一般而言,事务都是加在Service层的,但也可以加在Controller层。。                        

看了不少人的博客,总结出两个方法:

  • 在controller层写编程式事务

  • 将事务配置定义在Spring MVC的应用上下文(spring-mvc.xml)中

现在具体来说说怎么实现的:

1.在controller层写编程式事务【繁琐,不推荐】

spring-mybatis.xml中事物管理器的配置依旧

<!-- 配置数据源事务 --><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">    <property name="dataSource"  ref="dataSource"/></bean> <!--     注解方式配置事务 @Transactional    但因为是在controller中写编程式事务,这里可以不配置<tx:annotation-driven transaction-manager="transactionManager" />--><tx:annotation-driven transaction-manager="transactionManager" />

在controller中的方法里编写事务

//在每个controller中注入transactionManager@Resourceprivate PlatformTransactionManager transactionManager; @PostMapping(value = "setCode")@ResponseBodypublic 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"));    } }

2.将事务配置定义在Spring MVC的应用上下文(spring-mvc.xml)中【简单明了、一劳永逸】

spring-mybatis.xml中事物管理器配置不变

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

<!--    命名空间中 加入:    xmlns:tx="http://www.springframework.org/schema/tx"        http://www.springframework.org/schema/tx    http://www.springframework.org/schema/tx/spring-tx.xsd--><tx:annotation-driven/>

将@Transactional(rollbackFor = { Exception.class })注解打在Controller上

@Controller@RequestMapping(value = "/invoiceC")@Transactional(rollbackFor = { Exception.class })public class InvoiceController extends BaseController {      @Autowired    private InvoiceService invoiceService;     @Autowired    private InvoiceOrderService invoiceOrderService;     @Autowired    private InvoiceAddressService invoiceAddressService;     @Autowired    private BalanceRechangeOrderService bOrderService;         @PostMapping(value = "setCode")    @ResponseBody    public void setCode(Invoice invoice, InvoiceAddress invoiceAddress,String token,String orderIDs,                        Integer pid,HttpServletResponse response){        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);        printJson(response,result(200,"ok"));     }}

现在,我们来谈谈为什么之前??==》

  • 在spring-mybatis.xml的<aop:config>添加对Controller的声明式事务拦截

  • 在Controller的class加上@Transactional

两者均未生效呢???

原理:因为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注解

SSM下Controller层的事务配置问题

在写项目过程中遇到了多表联合修改数据时的事务问题,按照之前的学习,事务都是配置在service层中的,但是我的项目模块里一个service对应一个数据表,所以想在controller层加一个针对多个表的数据修改以及添加的事务配置。悲惨的是,在controller层配置事务出错没有回滚!

按照我已所接触的逻辑,控制层是不建议写业务逻辑的,所以在里面调用的是多个service层的接口(使用Autowired)来调用多个表的业务操作。但是多个表形成一个事务,所以我没找在service层里单独添加事务的合适的方法。如果有前辈想到合适的方法,望赐教!叩谢!

解决

原来的配置

首先是在service层上添加事务的配置,我这里的事务处理采用的是注解的方式,所以配置文件相较于配置事务的方式大大简化了。

首先命名空间中加入:

xmlns:tx="http://www.springframework.org/schema/tx"http://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsd

然后是xml文件的配置:

  <!-- service除了业务(操作dao)还要有事务 -->  <tx:annotation-driven  transaction-manager="txManager" />  <!-- 配置Spring的声明式事务管理器 -->  <bean id="txManager"  class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  <property name="dataSource" ref="dataSource"></property>  </bean>

其中,数据源我是配置在了dao层的配置文件中,由于都在spring的管理之下,所以在service直接使用是能够找到的。

以下是我的maven依赖的jar包版本: 

 <!-- https://mvnrepository.com/artifact/org.springframework/spring-tx -->  <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-tx</artifactId>      <version>5.1.5.RELEASE</version>  </dependency>  <!-- Spring jdbc事务管理 -->  <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->  <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-jdbc</artifactId>      <version>5.1.5.RELEASE</version>  </dependency>

以上是我起初的配置。但是仅仅这样是无法在controller层添加事务的。

修正后的配置

在service层的配置文件不变的情况下,我们想要在controller层添加事务,只需要在spring-mvc.xml中引入事务的注解驱动标签即可。

<!--在xml文件头部引入命名空间,参考serviice层--><tx:annotation-driven/>

为什么会这样?

首先我们来看配置文件的加载:

  <!-- 配置前端控制器 -->  <servlet>  <servlet-name>DispatcherServlet</servlet-name>  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  <init-param>      <param-name>contextConfigLocation</param-name>      <param-value>classpath:spring-mvc.xml</param-value>  </init-param>  </servlet>  <servlet-mapping>  <servlet-name>DispatcherServlet</servlet-name>  <url-pattern>*.action</url-pattern>  </servlet-mapping>  <!-- 配置spring容器加载的监听器 -->  <listener>  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  </listener>  <context-param>  <param-name>contextConfigLocation</param-name>  <param-value>classpath:spring-*.xml</param-value>  </context-param>

以上是我的web.xml的部分配置。在项目启动过程中,加载spring-mvc.xml是使用DispatcherServlet加载的,而加载spring-service.xml与spring-dao.xml使用的是ContextLoaderListener。

然后我们需要知道的是,ContextLoaderListener是早于DispatcherServlet启动的,而在ContextLoaderListener加载service层配置时controller并没有加载到容器中,但是此时事务的动态代理已经切入到了service层,所以后续的controller层并没有被增强。

因此,我们需要在controller层再次加入 <tx:annotation-driven/>。

关于“SSM怎么实现在Controller中添加事务管理”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注编程网行业资讯频道,小编每天都会为大家更新不同的知识点。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

SSM怎么实现在Controller中添加事务管理

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

SSM怎么实现在Controller中添加事务管理

这篇文章主要介绍“SSM怎么实现在Controller中添加事务管理”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“SSM怎么实现在Controller中添加事务管理”文章能帮助大家解决问题。SSM在
2023-06-29

spring怎么实现事务管理

Spring框架提供了多种方式来实现事务管理。下面是几种常见的方式:1. 声明式事务管理:使用Spring的事务管理器和注解或XML配置来声明事务管理规则。可以通过在方法或类级别上添加`@Transactional`注解来指定事务的属性(如
2023-09-28

Java中怎么实现多线程事务管理

Java中怎么实现多线程事务管理,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。一、继承Thread类第一种方法是继承Thread类,重写run()方法public clas
2023-06-20

怎么在Django中使用transaction管理事务

本篇文章给大家分享的是有关怎么在Django中使用transaction管理事务,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。1. transaction事务内不执行数据库的c
2023-06-14

怎么在Android应用中添加一个文件管理功能

这篇文章给大家介绍怎么在Android应用中添加一个文件管理功能,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。思路:获取存储器接口 遍历当前目录 利用ListView显示文件文件夹先是布局2023-05-31

Couchbase中怎么实现事务处理

Couchbase是一个NoSQL数据库,而NoSQL数据库通常不支持传统的ACID事务。然而,Couchbase最新版本中引入了事务处理的功能,通过使用CAS(Compare-And-Swap)操作和乐观并发控制来实现事务处理。在Cou
Couchbase中怎么实现事务处理
2024-03-08

VB.NET中怎么实现事务处理

今天就跟大家聊聊有关VB.NET中怎么实现事务处理,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。VB.NET事务处理代码示例:[Visual Basic] Public Sub
2023-06-17

C#/VB.NET怎么实现在PDF表格中添加条形码

这篇文章主要介绍了C#/VB.NET怎么实现在PDF表格中添加条形码的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇C#/VB.NET怎么实现在PDF表格中添加条形码文章都会有所收获,下面我们一起来看看吧。类库引
2023-06-30

PL/SQL中的事务管理与并发控制怎么实现

在PL/SQL中,事务管理和并发控制可以通过使用事务控制语句和锁机制来实现。事务控制语句包括BEGIN TRANSACTION、COMMIT和ROLLBACK,用于开始事务、提交事务和回滚事务。通过合理地使用这些语句,可以确保数据库操作的
PL/SQL中的事务管理与并发控制怎么实现
2024-05-07

怎么在C语言中实现内存管理

这篇文章给大家介绍怎么在C语言中实现内存管理,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。C语言是什么C语言是一门面向过程的、抽象化的通用程序设计语言,广泛应用于底层开发,使用C语言可以以简易的方式编译、处理低级存储器
2023-06-14

VB.NET中怎么实现事务处理操作

VB.NET中怎么实现事务处理操作,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。要定义一个事务,需要使用Begin tran命令,在这一命令之后的任何语句都将被认为是事务的
2023-06-17

JavaBean中怎么利用JDBC实现事务处理

今天就跟大家聊聊有关JavaBean中怎么利用JDBC实现事务处理,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。JDBC(Java Data Base Connectivity,ja
2023-06-17

怎么在Spring中利用@Transactional实现事务回滚

今天就跟大家聊聊有关怎么在Spring中利用@Transactional实现事务回滚,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。一、使用场景举例在了解@Transactional怎
2023-05-30

怎么在Spring 5.0中使用log4j2实现日志管理

本篇文章为大家展示了怎么在Spring 5.0中使用log4j2实现日志管理,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。先引入log4j 2的三个jar包log4j-api-2.10.0.jarl
2023-05-30

权限管理模块中动态加载Vue组件怎么实现

本篇内容介绍了“权限管理模块中动态加载Vue组件怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!登录状态保存当用户登录成功之后,需要将
2023-06-19

使用python怎么实现在协程中增加任务

这篇文章主要介绍了使用python怎么实现在协程中增加任务,此处通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考价值,需要的朋友可以参考下:python是什么意思Python是一种跨平台的、具有解释性、编译性、互动性和面向
2023-06-06

怎么在Java中利用JDBC实现一个事务功能

本文章向大家介绍怎么在Java中利用JDBC实现一个事务功能,主要包括怎么在Java中利用JDBC实现一个事务功能的使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。Java是什么Java是一门面
2023-05-30

怎么在Android中利用RecyclerView实现一个频道管理功能

本篇文章给大家分享的是有关怎么在Android中利用RecyclerView实现一个频道管理功能,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。需要在build里添加依赖 com
2023-05-31

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录