更新
我发现我将A类注入C类,扩展了一个外部类, 那个班不是春天管理的,就像这样:
public class C extends ExternalClass {
@AutoWired
private A a;
//doSomething...
}
这应该是交易失败的主要原因。
另一个问题:是否有任何方法可以使A类的Spring管理事务注入到未由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 config:
@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。 然而,他们都没有工作。
答案 0 :(得分:0)
问题是如果将一个类注入另一个不是spring托管bean的类,那么spring transaction管理将失败。 因此,在发生事务失败时,请检查是否存在错误的依赖注入。