【发布时间】: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