在SpringBoot应用程序中使用@Configuration和AspectJ时,事务管理不起作用

时间:2019-05-22 10:09:45

标签: spring spring-boot transactions spring-transactions spring-mybatis

SpringBoot中,我们可以将@EnableTransactionManagement添加到应用程序类中,并将@Transactional添加到相关的服务方法中,以使事务管理正常工作。

但是,我认为向每个需要事务的服务方法添加@Transactional很无聊,我想像下面这样使用统一的方法来做到这一点(这意味着不使用@Transactional):

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  <property name="dataSource" ref="dataSource"/>
</bean>

<tx:advice id="txAdvice" transaction-manager="transactionManager">
    <tx:attributes>
       <tx:method name="*" rollback-for="Exception" propagation="REQUIRED"/>
       <tx:method name="query*" read-only="true"/>
       <tx:method name="get*" read-only="true"/>
       <tx:method name="find*" read-only="true"/>
       <tx:method name="select*" read-only="true"/>
    </tx:attributes>
</tx:advice>

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

经过研究,我发现我们可以使用@ImportResource()来导入xml配置文件。但是我想使用注释的方式来做,所以我在下面编写代码(ORM框架为mybatis):

@Configuration
public class TransactionConfig {

    @Bean("txInterceptor")
    public TransactionInterceptor getInterceptor(PlatformTransactionManager tx) {
        return new TransactionInterceptor(tx, transactionAttributeSource());
    }

    @Bean("txAdvisor")
    public AspectJExpressionPointcutAdvisor pointcutAdvisor(TransactionInterceptor txInterceptor) {
        AspectJExpressionPointcutAdvisor advisor = new AspectJExpressionPointcutAdvisor();
        advisor.setAdvice(txInterceptor);
        advisor.setExpression("execution (* com.xxx.yyy.service.*.*(..))");
        return advisor;
    }

    @Bean("txSource")
    public TransactionAttributeSource transactionAttributeSource() {
        NameMatchTransactionAttributeSource source = new NameMatchTransactionAttributeSource();

        RuleBasedTransactionAttribute readyOnlyTx = new RuleBasedTransactionAttribute();
        readyOnlyTx.setReadOnly(true);
        readyOnlyTx.setPropagationBehavior(TransactionDefinition.PROPAGATION_NOT_SUPPORTED);

        RuleBasedTransactionAttribute requiredTx = new RuleBasedTransactionAttribute();
        requiredTx.setRollbackRules(Collections.singletonList(new RollbackRuleAttribute(Exception.class)));
        requiredTx.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);

        Map<String, TransactionAttribute> txMap = new HashMap<>();

        txMap.put("find*", readyOnlyTx);
        txMap.put("get*", readyOnlyTx);
        txMap.put("select*", readyOnlyTx);

        txMap.put("add*", requiredTx);
        txMap.put("insert*", requiredTx);
        txMap.put("update*", requiredTx);
        txMap.put("delete*", requiredTx);

        source.setNameMap(txMap);

        return source;
    }
}

测试代码:

@RunWith(SpringRunner.class)
@SpringBootTest
public class UserServiceTest {

    @Autowired
    private IUserService userService;

    @Test
    public void testAddUser(){
        UserModel uModel = new UserModel();
        uModel.setUsername("vdu");
        uModel.setPassword("123456");
        uModel.setPhone("15112971150");
        uModel.setEmail("vdu@mail.com");
        uModel.setUserType(UserConstants.USER_TYPE_COMMON);
        uModel.setRealName("Test User");

        userService.addUser(uModel);
    }
}

但是,当我运行测试代码时,我得到下面的输出,消息 com.mysql.jdbc.JDBC4Connection@63f6bed1]将不会由Spring管理,表明事务管理未启动。我在Google上搜索过,但仍然找不到解决方法,有人可以帮我分析一下吗?预先感谢!

[INFO ] 2019-05-22 17:30:00.534 下午 [main] PoolBase - HikariPool-1 - Driver does not support get/set network timeout for connections. (com.mysql.jdbc.JDBC4Connection.getNetworkTimeout()I)
[DEBUG] 2019-05-22 17:30:00.538 下午 [main] HikariPool - HikariPool-1 - Added connection com.mysql.jdbc.JDBC4Connection@63f6bed1
[INFO ] 2019-05-22 17:30:00.541 下午 [main] HikariDataSource - HikariPool-1 - Start completed.
[DEBUG] 2019-05-22 17:30:00.548 下午 [main] SpringManagedTransaction - JDBC Connection [HikariProxyConnection@1288163341 wrapping com.mysql.jdbc.JDBC4Connection@63f6bed1] will not be managed by Spring

0 个答案:

没有答案