Spring中为啥@Transactional注解打在Controller层的方法上不起作用

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring中为啥@Transactional注解打在Controller层的方法上不起作用相关的知识,希望对你有一定的参考价值。

项目中采用Spring声明式事务,在Controller层的方法上打事务标签不起作用,求指教。

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="oracle.jdbc.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:@localhost:1521:orcl" />
<property name="username" value="xxx" />
<property name="password" value="xxxx" />
  </bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory" />
  </bean>

  <tx:annotation-driven transaction-manager="transactionManager" />


你的spring配置里加了<tx:annotation-driven transaction-manager="transactionManager" />这个注解开关了吗?事务管理器。加了才能这么注。 如上。

追问

加了

参考技术A 不可能不会起作用的,你是不是在service层用try catch捕捉异常了?或者你数据库用的是mysql,引擎用的是myisam?追问

不是啊

Spring 事务注解@Transactional

事务管理一般有编程式和声明式两种,编程式是直接在代码中进行编写事物处理过程,而声名式则是通过注解方式或者是在xml文件中进行配置,相对编程式很方便。

而注解方式通过@Transactional 是常见的。我们可以使用@EnableTransactionManagement 注解来启用事务管理功能,该注解可以加在启动类上或者单独加个配置类来处理。

1、Transactional 注解的属性

  • name 当在配置文件中有多个 TransactionManager , 可以用该属性指定选择哪个事务管理器。
  • propagation 事务的传播行为,默认值为 REQUIRED。
  • isolation 事务的隔离度,默认值采用 DEFAULT。
  • timeout 事务的超时时间,默认值为-1。如果超过该时间限制但事务还没有完成,则自动回滚事务。
  • read-only 指定事务是否为只读事务,默认值为 false;为了忽略那些不需要事务的方法,比如读取数据,可以设置 read-only 为 true。
  • rollback-for 用于指定能够触发事务回滚的异常类型,如果有多个异常类型需要指定,各类型之间可以通过逗号分隔。
  • no-rollback- for 抛出 no-rollback-for 指定的异常类型,不回滚事务。

2、Transactional应用

@Transactional 可以加在方法上,表示对当前方法配置事务也可以添加到类级别上。

也可以添加到类级别上。当把@Transactional 注解放在类级别时,表示所有该类的公共方法都配置相同的事务属性信息。

当类级别配置了@Transactional,方法级别也配置了@Transactional,应用程序会以方法级别的事务属性信息来管理事务,即方法级别的事务属性信息会覆盖类级别的相关配置信息。

3、附注

  3.1 @Transactional 注解应用到 public 方法,才能进行事务管理。因为aop会进行拦截是否是public方法

//AbstractFallbackTransactionAttributeSource类
  
    protected TransactionAttribute computeTransactionAttribute(Method method,
        Class<?> targetClass) {
            // Don‘t allow no-public methods as required.
            if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
    return null;}

  3.2 propagation 属性

  下面三种 propagation 可以不启动事务。错误的配置这三种 propagation,事务可能不会发生回滚。

  • TransactionDefinition.PROPAGATION_SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。
  • TransactionDefinition.PROPAGATION_NOT_SUPPORTED:以非事务方式运行,如果当前存在事务,则把当前事务挂起。
  • TransactionDefinition.PROPAGATION_NEVER:以非事务方式运行,如果当前存在事务,则抛出异常。

  3.3 rollbackFor 属性
  默认情况下,如果在事务中抛出了未检查异常(继承自 RuntimeException 的异常)或者 Error,则 Spring 将回滚事务;除此之外,Spring 不会回滚事务。
  可以通过rollbackFor来制定在食物中抛出的其他类型的异常来支持事务回滚,例:

@Transactional(propagation= Propagation.REQUIRED, rollbackFor= MyException.class)

  若在目标方法中抛出的异常是 rollbackFor 指定的异常的子类,事务同样会回滚。

 

源码参照:Github

以上是关于Spring中为啥@Transactional注解打在Controller层的方法上不起作用的主要内容,如果未能解决你的问题,请参考以下文章

Spring 事务注解@Transactional

spring @Transactional注解参数详解

spring @Transactional注解参数详解(13)

spring @Transactional注解参数详解

Spring——事务注解@Transactional建议收藏

spring @Transactional 事务注解的坑