【问题解决】SSM-@Transactional注解事务无效探讨

Spring SpringMVC MyBatis框架中-@Transactional注解事务无效解决方法

SpringMVC-Spring-MyBatis框架
数据库:SQL SERVER 2008
以前都是用的MySQL数据库,没有出现这个问题,现在换成sql server了,结果事务没有起作用了。

经过一番测试:
排除以下几个问题:
1.数据库原因,不存在的。MySQL中只有InnoDB引擎支持事务。SqlServer2008的企业版作为收费数据库,不可能不支持事务操作。
2.异常类型不是unchecked异常,我写的异常是1/0,为了保险起见,我还抛出RuntimeException试了,结果也是没有回滚。
3.是不是配置文件的没配置好,比如Bean,比如:

    <!-- 配置事物管理类 -->
    <bean id="transactionManager"
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dynamicDataSource" />
    </bean>
    <!-- 开启注解式事物扫描 -->
    <tx:annotation-driven transaction-manager="transactionManager"  />

检查几遍,排除这个原因。
4.还有一种情况,因为我以前写的都是对一个数据库的操作,现在是一个数据源多个数据库操作,当时有点怀疑我是不是少配置了什么,导致多数据库时无法启动事务,于是便还原到一个数据库,结果事务还是无效,排除此问题

经过一番折腾,在网上找到一篇文章,说原因是applicationContext.xml的父容器先于Servlet的子容器生效,将Service提前加载了。

于是验证了一下,首先去掉Service实现类的@Service注解,在spring.xml(也就是applicationContext.xml,我起名是spring.xml),配置该类的Bean:

<bean id="sysUserServiceImp" class="cn.kx59.user.service.imp.SysUserServiceImp"></bean>

结果运行之后,事务起作用了。

原因如下:
Spring容器优先加载由ServletContextListener(对应applicationContext.xml,我这里是spring.xml)产生的父容器,而SpringMVC(对应spring-mvc.xml)产生的是子容器。
子容器Controller进行扫描装配时装配的@Service注解的实例是没有经过事务加强处理,即没有事务处理能力的Service,而父容器进行初始化的Service是保证事务的增强处理能力的。如果不在子容器中将Service exclude掉,此时得到的将是原样的无事务处理能力的Service。
所以我们要在扫描的时候在子容器中将Service exclude掉就好了。

也就是在spring-mvc.xml中进行如下修改:

    <!--扫描Controller-->
    <context:component-scan base-package="cn.kx59">
        <context:include-filter type="annotation"
                                expression="org.springframework.stereotype.Controller" />
        <!--下面这个是防止事务没起作用,spring.xml的父容器先于Servlet的子容器生效,将Service提前加载了。这里不用再进行加载装配-->
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service" />
    </context:component-scan>

注意: 请将@Transactional注解写在实现类的方法或类上!不建议写在接口类中!
Spring团队的建议是你在具体的类(或类的方法)上使用 @Transactional 注解,而不要使用在类所要实现的任何接口上。你当然可以在接口上使用 @Transactional 注解,但是这将只能当你设置了基于接口的代理时它才生效。因为注解是不能继承的,这就意味着如果你正在使用基于类的代理时,那么事务的设置将不能被基于类的代理所识别,而且对象也将不会被事务代理所包装(将被确认为严重的)。因此,请接受Spring团队的建议并且在具体的类上使用 @Transactional 注解。

在以上解决方法中,若将@Transactional 注解写在接口上,则无法实现事务。所以请将 @Transactional 注解写在实现类中!

本文章由[谙忆]编写, 所有权利保留。
欢迎转载,分享是进步的源泉。

转载请注明出处:http://chenhaoxiang.cn

本文源自人生之旅_谙忆的博客

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SSM使用@Transactional注解来开启事务事务是在Spring框架处理数据库的增删改操作时非常重要的一部分。通过使用@Transactional注解,可以将一系列数据库操作作为一个事务来处理,保证这些操作要么全部成功提交,要么全部回滚。@Transactional注解可以应用于类级别和方法级别。 在SSM使用@Transactional注解的步骤如下: 1. 首先,在Spring配置文件配置事务管理器的bean。可以使用Spring的内置事务管理器或者集成其他的事务管理器,如JTA事务管理器。 2. 然后,在需要开启事务的类或方法上添加@Transactional注解注解可以添加在类级别上,表示所有的方法都将被包装在同一个事务;也可以添加在方法级别上,表示该方法将被包装在一个独立的事务。 3. 当程序执行到被@Transactional注解修饰的方法时,Spring框架会自动开启一个事务,并在方法执行完毕后根据返回结果决定是提交事务还是回滚事务。 例如,如果在SSM项目的某个Service类的方法上需要开启事务,可以在该方法上添加@Transactional注解,示例如下: ```java @Service public class UserService { @Autowired private UserDao userDao; @Transactional public void saveUser(User user) { // 执行数据库操作 userDao.save(user); } } ``` 在上述示例,saveUser方法被@Transactional注解修饰,表示该方法将被包装在一个事务。如果在方法执行过程发生了异常,事务将会回滚,数据库操作将会撤销;如果方法执行成功,事务将会提交,数据库操作将会生效。 总结起来,使用@Transactional注解可以方便地管理事务,并确保数据库操作的一致性和完整性。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [spring的隔离级别](https://download.csdn.net/download/handsome221/87368148)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [SSM入门到精通项目实战(附源码)](https://download.csdn.net/download/weixin_26971157/19603351)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [SSM @Transactional 事务控制](https://blog.csdn.net/weixin_43432438/article/details/124421316)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值