【问题标题】:Correct use of Hazelcast Transactional Map in an Spring Boot app在 Spring Boot 应用程序中正确使用 Hazelcast Transactional Map
【发布时间】:2017-08-25 21:44:42
【问题描述】:

我正在研究 Hazelcast Transactional Map 的概念证明。为此,我正在编写一个 Spring Boot 应用程序并使用 Atomikos 作为我的 JTA/XA 实现。

此应用必须更新事务映射并通过在同一事务中插入新行来更新数据库表。

我正在使用 JPA / SpringData / Hibernate 来处理数据库。

所以应用程序有一个组件(一个用@Component 注释的 JAVA 类),它有一个名为 agregar() 的方法(添加西班牙语)。这个方法用@Transactional注解(org.springframework.transaction.annotation.Transactional)

该方法必须作为一个单元执行两项任务:首先必须更新从 Hazelcast 实例检索的 TransactionalMap,其次必须使用从 JpaRepository (org.springframework.data.jpa.repository.JpaRepository) 扩展的存储库更新数据库表

这是我写的代码:

@Transactional
public void agregar() throws NotSupportedException, SystemException, IllegalStateException, RollbackException, SecurityException, HeuristicMixedException, HeuristicRollbackException, SQLException {

    logger.info("AGRENADO AL MAPA ...");

    HazelcastXAResource xaResource = hazelcastInstance.getXAResource();

    UserTransactionManager tm = new UserTransactionManager();
    tm.begin();

    Transaction transaction = tm.getTransaction();
    transaction.enlistResource(xaResource);

    TransactionContext context = xaResource.getTransactionContext();
    TransactionalMap<TaskKey, TaskQueue> mapTareasDiferidas = context.getMap("TAREAS-DIFERIDAS");

    TaskKey taskKey = new TaskKey(1L);
    TaskQueue taskQueue = mapTareasDiferidas.get(taskKey);

    Integer numero = 4;

    Task<Integer> taskFactorial = new TaskImplFactorial(numero);

    taskQueue = new TaskQueue();
    taskQueue.getQueue().add(taskFactorial);

    mapTareasDiferidas.put(taskKey, taskQueue);

    transaction.delistResource(xaResource, XAResource.TMSUCCESS);
    tm.commit();

    logger.info("AGRENADO A LA TABLA ...");

    PaisEntity paisEntity = new PaisEntity(100, "ARGENTINA", 10);
    paisRepository.save(paisEntity);

}

此代码正在运行:如果其中一个任务引发异常,则两个任务都会回滚。

我的问题是:

  1. 这段代码真的正确吗?
  2. 为什么 @Transactional 不负责在地图中提交更改,而我必须明确地自己完成?

项目的完整代码在 Github 上:https://github.com/diegocairone/hazelcast-maps-poc

提前致谢

【问题讨论】:

  • 你使用哪个版本的 Hazelcast?
  • Hazelcast 3.6.7 嵌入 Spring Boot 1.4.5

标签: spring-boot hazelcast spring-transactions jta atomikos


【解决方案1】:

最后我意识到我必须注入“UserTransactionManager”对象并从中获取事务。

还需要使用 JTA/XA 实现。我选择了 Atomikos,并且必须在 MS SQL Server 中启用 XA 事务。

工作示例可在 Github https://github.com/diegocairone/hazelcast-maps-poc on branch atomikos-datasource-mssql 获得

【讨论】:

    【解决方案2】:

    从 Hazelcast 3.7 开始,您可以使用 HazelcastTransactionManager 摆脱样板代码来开始、提交或回滚事务,这是与 Spring Transaction API 一起使用的 PlatformTransactionManager 实现。 您可以找到示例here

    此外,Hazelcast 可以参与与 Atomikos 的 XA 交易。 Here's a doc

    谢谢

    【讨论】:

    • 我已更新到 Hazelcast 3.7.5,但仍然遇到 atomikos 集成和 Hazelcast ManagedTransactionalTask​​Context 的问题。你能帮我解决这个问题吗?我将发布更多详细信息作为答案。
    【解决方案3】:

    我已经更新到 Hazelcast 3.7.5 并将以下代码添加到 HazelcastConfig 类。

    @Configuration
    public class HazelcastConfig {
    ...
    
    
    @Bean
    public HazelcastInstance getHazelcastInstance() {
        ....
    }
    
    
    @Bean
    public HazelcastTransactionManager getTransactionManager() {
        HazelcastTransactionManager transactionManager = new HazelcastTransactionManager(getHazelcastInstance());
        return transactionManager;
    }
    
    @Bean
    public ManagedTransactionalTaskContext getTransactionalContext() {
        ManagedTransactionalTaskContext transactionalContext = new ManagedTransactionalTaskContext(getTransactionManager());
        return transactionalContext;
    }
    

    当我运行应用程序时,我得到了这个异常:

    org.springframework.beans.factory.NoSuchBeanDefinitionException: 否 名为“transactionManager”的 bean 可用:无匹配 为限定符找到 PlatformTransactionManager bean 'transactionManager' - 限定符匹配和 bean 名称都不匹配!

    代码在 Github 的一个新分支上可用:atomikos-datasource-mssql-hz37

    提前致谢

    【讨论】:

    • 类路径中有 hazelcast-spring jar 吗?
    • 是的。它在 pom.xml 中声明
    猜你喜欢
    • 2021-01-06
    • 2019-03-08
    • 2018-12-30
    • 2020-03-30
    • 2021-05-30
    • 2019-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多