【问题标题】:Custom platform transaction manager in spring春季自定义平台事务管理器
【发布时间】:2015-04-18 06:26:10
【问题描述】:

我正在尝试在 Spring Boot 应用程序中实现自定义事务缓存。我创建了自己的 AbstractPlatformTransactionManager 实现和一些单元测试,它们显示事务按预期工作。然而,真正的应用程序忽略了我的事务管理器——它的方法永远不会被调用。我做错了什么?谢谢。

事务管理器实现:

@Component
public class CacheTransactionManager extends AbstractPlatformTransactionManager{
    @Override
    protected Object doGetTransaction() throws TransactionException {
    ...
    }
...
}

缓存事务配置:

@Configuration
@EnableTransactionManagement(mode = AdviceMode.ASPECTJ)
public class CacheTransactionConfiguration {

    @Bean(name = "cacheTransactionManager")
    public PlatformTransactionManager cacheTransactionManager() {
        return new CacheTransactionManager();
    }  

}

自定义事务注释(我也试过没有这个,但没有区别):

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Transactional(value = "cacheTransactionManager", rollbackFor = Exception.class)
public @interface CacheTransactional {

}

缓存服务:

@Component
public class CacheService {
    @CacheTransactional
    public void add(Object o){
        ...
    }
}

工作 JUnit 测试:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = TestApplication.class)
@Configuration
@EntityScan(...)
@IntegrationTest
@TransactionConfiguration(defaultRollback = false)
public class CacheTransactionManagerTest {
    @Autowired
    private CacheService cacheService;

    @Test
    @CacheTransactional
    public void transactionTest(){
        cacheService.add(new Object());
    }
}

不工作的检票口应用程序主类(忽略 cacheTransactionManager):

@Configuration("MyApplication")
@EnableAutoConfiguration
@EntityScan(...)
@EnableJpaRepositories(...)
@EnableTransactionManagement(mode = AdviceMode.ASPECTJ)
@ComponentScan(...)
@ImportResource({...})
public class MyApplication extends AuthenticatedWebApplication {
...
}

我的环境:Java 8、Spring Boot 1.2.1、Spring 4.1.4、Spring data JPA 1.7.2、Hibernate 4.3.7、Apache Tomcat 8.0.15、Wicket 6.17.0

【问题讨论】:

  • 应该如何准确处理@CacheTransactional?你能解释一下你想要做什么吗?
  • 我想在执行 @CacheTransactional 方法之前实现一个事务创建(调用事务管理器中的方法 doGetTransaction 和 doBegin),当方法成功完成时,调用 doCommit ,否则(以防万一异常)doRollback 被调用。这在 junit 测试中有效,但在应用程序中无效。

标签: spring transactions


【解决方案1】:

我发现了一些新的事实:

  • 当我从 CacheTransactionConfiguration 上的 @EnableTransactionManagement 中删除 AdviceMode.ASPECTJ 时,事务开始工作,但事务的传播被忽略 - 从一个 @CacheTransactional 方法到另一个 @CacheTransactional 方法的嵌套调用总是会创建新事务。 JUnit 测试和实际应用中的行为相同。

  • 当 AdviceMode.ASPECTJ 设置为 CacheTransactionConfiguration 时,但我从 junit 测试中删除了 @CacheTransactional 注释,事务也在 juint 中停止工作(在测试主体中调用了一个 @CacheTransaction 方法,因此应该创建一个事务) .

  • 应用程序日志包含以下条目: o.s.c.a.ConfigurationClassBeanDefinitionReader isOverriddenByExistingDefinition:290 - 跳过 [BeanMethod:name=cacheTransactionManager,declaringClass=x.y.z.CacheTransactionConfiguration] 的 bean 定义:bean 'cacheTransactionManager' 的定义已经存在。此顶级 bean 定义被视为覆盖。

所以我可以让它工作,但没有传播......

【讨论】:

    【解决方案2】:

    对于传播,你需要告诉 Spring 的 @Transactional 应用什么传播模式。您可以定义多个 tx 注释,每个都继承自 @Transactional,但具有不同的传播模式。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-22
      • 2013-02-24
      • 1970-01-01
      • 2017-08-11
      • 2014-02-19
      • 1970-01-01
      • 2014-08-10
      • 1970-01-01
      相关资源
      最近更新 更多