当前位置: 首页 > 知识库问答 >
问题:

事务配置在Spring启动中失败

章阳波
2023-03-14

更新:

我发现我将类A注入到扩展外部类的类C中,该类不受spring管理,如下所示:

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

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

另一个问题:有没有办法让spring管理类A的事务,该类已经注入到非spring处理的anothor类中?

我正在用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。然而,它们都不起作用。

共有1个答案

越嘉茂
2023-03-14

问题是,如果您将一个类注入到另一个不是spring管理的bean的类中,那么spring事务管理将失败。因此,当事务失败时,检查是否存在错误的依赖注入。

 类似资料:
  • 问题内容: 我们有: MyInterface有一个方法:。 当go()执行时,我们开始一个新的事务,该事务在方法完成时进行提交/回滚-很好。 现在,在go()中,我们在MyClass中调用了具有的私有方法。看来Spring会“忽略” REQUIRES_NEW批注,并且不会启动新的事务。我相信这是因为Spring AOP在接口级别(MyInterface)上运行,并且不会拦截对MyClass方法的任

  • 我试图将Spring引导指南中的管理事务示例扩展到两个数据源,但是@事务注释似乎只适用于其中一个数据源。 在"Application.java"中,我添加了两个数据源及其Jdbc模板的bean。在"BookingService.java"中,我使用了属于第二个数据源的JdbcTemboard。 这是我的“Application.java”: 下面是“BookingService.java”: 这些

  • “Spring-Boot-AutoConfigure”,版本:'2.4.1'

  • 我正在学习Spring Boot的JavaBrains教程。 我的项目结构如下: courseapiapp.java: topicService.java: topic.java: topicRepository.java: 编辑:我读到的这篇文章解释了@AutoWired在没有实际实现接口的情况下是如何工作的。我明白解决办法,但我不明白如何解决我的问题。显然,设置和配置Spring数据的方式存在

  • 当我试图启动SpringBoot主应用程序时,出现以下异常。为什么我会得到这个特例。 异常: Spring boot主java类