在Spring Boot应用程序中正确使用Hazelcast Transactional Map

时间:2017-03-31 14:56:08

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

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

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

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

因此,app有一个组件(一个用@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没有负责提交地图中的更改,我必须自己明确地执行此操作?
  3. 项目的完整代码可以在Github上找到:https://github.com/diegocairone/hazelcast-maps-poc

    提前致谢

3 个答案:

答案 0 :(得分:0)

最后我意识到我必须注入&#39; UserTransactionManager&#39;反对并从中获取交易。

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

工作示例可在分支atomikos-datasource-mssql上的Github https://github.com/diegocairone/hazelcast-maps-poc获得

答案 1 :(得分:0)

从Hazelcast 3.7开始,您可以使用HazelcastTransactionManager来摆脱样板代码来开始,提交或回滚事务,PlatformTransactionManager是一个与{Spring} API一起使用的ffmpeg -i test720.mp4 -filter_complex "hqdn3d=1.5:1.5:6:6,scale=w=if(gt(dar\,854/480)\,min(854\,iw‌​sar)\,2*trunc(iwsaro‌​h/ih/2)):h=if(gt(dar‌​\,854/480)\,2*trunc(‌​ihow/iw/sar/2)\,min(‌​480\,ih)):flags=bicu‌​bic,setsar=1[we];mov‌​ie=actorimage.png[wm‌​];[we][wm]overlay=30‌​:main_h-overlay_h-12‌​0,subtitles=add.ass" -c:v libx264 -crf 18 -preset veryslow -tune film -refs 8 -bf 6 -aq-mode 2 -c:a copy -f mp4 720.mp4实现。 您可以找到示例here

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

谢谢

答案 2 :(得分:0)

我已更新为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:没有   bean命名为&#39; transactionManager&#39;可用:没有匹配   为限定符找到PlatformTransactionManager bean   &#39; transactionManager的&#39; - 无论是限定符匹配还是bean名称匹配!

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

提前致谢