【问题标题】:Transaction configure failed in Spring BootSpring Boot 中的事务配置失败
【发布时间】:2018-01-05 13:57:22
【问题描述】:

更新:

我发现我将 A 类注入到 C 类中,C 类扩展了一个外部类, 并且该课程不是由 spring 管理的,就像这样:

public class C extends ExternalClass {    
    @AutoWired
    private A a;
    //doSomething...    
}

这应该是交易失败的主要原因。

另一个问题:有什么方法可以让spring管理A类的事务,该事务已经注入到另一个未被spring处理的类中?


我正在用 Spring Boot 和 Mybatis 构建一个项目。

我有一个服务类无法创建事务连接并且不会执行回滚的问题。

我发现如果我在B类中去掉A类的注入,像这样:

class A{
    //@Autowired
    //private B b;
    // b is not used in this class
    @Autowired
    private ADao dao;
}

class B{
    @Autowired 
    private BDao dao;

    //Transaction of this method failed
    //session didn't roll back
     public void (){
          dao.insert(new Entity ());
          //Exception here
     }
}

B 类创建的连接将是事务性的。两个类都在同一个包中,但如果我添加该注入,事务将失败。让我很困惑的是B类可以注入其他类,事务也可以很好地工作。

这是日志:

2018-01-05 21:30:33.861 DEBUG 10346 --- [http-nio-8099-exec-2] org.mybatis.spring.SqlSessionUtils       97 : Creating a new SqlSession
2018-01-05 21:30:33.866 DEBUG 10346 --- [http-nio-8099-exec-2] org.mybatis.spring.SqlSessionUtils       148 : SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3aeb5ca8] was not registered for synchronization because synchronization is not active
2018-01-05 21:30:33.888 DEBUG 10346 --- [http-nio-8099-exec-2] o.s.jdbc.datasource.DataSourceUtils      110 : Fetching JDBC Connection from DataSource
2018-01-05 21:30:33.888 DEBUG 10346 --- [http-nio-8099-exec-2] o.s.j.d.DriverManagerDataSource          142 : Creating new JDBC DriverManager Connection to [jdbc:mariadb://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true]
2018-01-05 21:30:33.905 DEBUG 10346 --- [http-nio-8099-exec-2] o.m.s.t.SpringManagedTransaction         87 : JDBC Connection [org.mariadb.jdbc.MySQLConnection@2bad8689] will not be managed by Spring
2018-01-05 21:30:33.908 DEBUG 10346 --- [http-nio-8099-exec-2] p.c.z.admin.dao.UserDao.insertSelective  159 : ==>  Preparing: INSERT INTO sys_user ( id,username ) VALUES( ?,? ) 
2018-01-05 21:30:33.916 DEBUG 10346 --- [http-nio-8099-exec-2] p.c.z.admin.dao.UserDao.insertSelective  159 : ==> Parameters: null, test(String)
2018-01-05 21:30:33.929 DEBUG 10346 --- [http-nio-8099-exec-2] p.c.z.admin.dao.UserDao.insertSelective  159 : <==    Updates: 1
2018-01-05 21:30:33.932 DEBUG 10346 --- [http-nio-8099-exec-2] p.c.z.a.d.U.insertSelective!selectKey    159 : ==>  Executing: SELECT LAST_INSERT_ID() 
2018-01-05 21:30:33.940 DEBUG 10346 --- [http-nio-8099-exec-2] p.c.z.a.d.U.insertSelective!selectKey    159 : <==      Total: 1
2018-01-05 21:30:33.942 DEBUG 10346 --- [http-nio-8099-exec-2] org.mybatis.spring.SqlSessionUtils       191 : Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3aeb5ca8]

我尝试了 3 种方式来配置事务:

使用 java 配置:

@Bean(name = "transactionInterceptor")
public TransactionInterceptor transactionInterceptor(PlatformTransactionManager platformTransactionManager) {
    TransactionInterceptor transactionInterceptor = new TransactionInterceptor();
    transactionInterceptor.setTransactionManager(platformTransactionManager);
    Properties transactionAttributes = new Properties();
    transactionAttributes.setProperty("insert*","PROPAGATION_REQUIRED,-Throwable");
    transactionAttributes.setProperty("update*","PROPAGATION_REQUIRED,-Throwable");
    transactionAttributes.setProperty("delete*","PROPAGATION_REQUIRED,-Throwable");
    transactionAttributes.setProperty("select*","PROPAGATION_REQUIRED,-Throwable,readOnly");
    transactionInterceptor.setTransactionAttributes(transactionAttributes);
    return transactionInterceptor;
}

@Bean
public BeanNameAutoProxyCreator transactionAutoProxy() {
    BeanNameAutoProxyCreator transactionAutoProxy = new BeanNameAutoProxyCreator();
    transactionAutoProxy.setProxyTargetClass(true);
    transactionAutoProxy.setBeanNames("*ServiceImpl");
    transactionAutoProxy.setInterceptorNames("transactionInterceptor");
    return transactionAutoProxy;
}

与xml:

<tx:advice id="txAdvice" transaction-manager="transactionManager">
    <tx:attributes>
        <tx:method name="save*" propagation="REQUIRED"/>
        <tx:method name="del*" propagation="REQUIRED"/>
        <tx:method name="update*" propagation="REQUIRED"/>
        <tx:method name="insert*" propagation="REQUIRED"/>
        <tx:method name="*" rollback-for="Exception"/>
    </tx:attributes>
</tx:advice>

<aop:config>
    <aop:pointcut id="services"
                  expression="execution(* root.*.service.*.*(..))"/>
    <aop:advisor pointcut-ref="services" advice-ref="txAdvice"/>
</aop:config>

和@Transactional。 然而,它们都不起作用。

【问题讨论】:

  • 您不需要事务配置,它是开箱即用的配置...您只需要添加@Transactional。如果有错误发布您得到的异常/堆栈跟踪。
  • 我试过了,但没有用。
  • 那么您的设置在某处出现问题(或者您在此处发布的代码并未反映实际代码)。 @Transactional 就是您所需要的。还有什么让你认为交易失败了?如前所述,如果有例外等,请将其添加到您的问题中。
  • 我不确定注入是否是失败的主要原因。我认为这应该是由配置引起的。也许我应该再次检查我的项目。
  • 我在某些类中做了一些异常,只有一个类没有回滚。

标签: spring-boot spring-transactions


【解决方案1】:

问题是,如果你将一个类注入到另一个不是 Spring 托管 bean 的类中,那么 Spring 事务管理将失败。 所以在事务失败的时候,去检查一下是否有错误的依赖注入。

【讨论】:

    猜你喜欢
    • 2015-06-02
    • 1970-01-01
    • 2017-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-10
    • 1970-01-01
    • 2015-04-24
    相关资源
    最近更新 更多