2017-03-31 1 views
0

Je travaille sur une preuve de concept de la carte transactionnelle Hazelcast. Pour ce faire, j'écris une application Spring Boot et j'utilise Atomikos comme implémentation JTA/XA.Utilisation correcte de la carte transactionnelle Hazelcast dans une application Spring Boot

Cette application doit mettre à jour une carte transactionnelle et également mettre à jour une table de base de données en insérant une nouvelle ligne tout au sein de la même transaction. J'utilise JPA/SpringData/Hibernate pour travailler avec la base de données. J'utilise JPA/SpringData/Hibernate. Donc l'application a un composant (une classe JAVA annotée avec @Component) qui a une méthode appelée agregar() (ajouter en espagnol). Cette méthode est annotée avec @Transactional (org.springframework.transaction.annotation.Transactional)

La méthode doit effectuer deux tâches en tant qu'unité: premièrement, mettre à jour une TransactionalMap extraite de l'instance Hazelcast et, deuxièmement, mettre à jour une table de base de données à l'aide d'un dépôt étendu de JpaRepository (org.springframework.data.jpa.repository.JpaRepository)

Voici le code que je l'ai écrit:

@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); 

} 

Ce code fonctionne: si l'une des tâches jeter un exception, les deux sont annulées.

Mes questions sont les suivantes:

  1. Est-ce code fait correct?
  2. Pourquoi @Transactional ne prend-il pas soin de valider les changements dans la carte et je dois le faire explicitement par moi-même?

Le code complet du projet est disponible en Github: https://github.com/diegocairone/hazelcast-maps-poc

Merci à l'avance

+0

version de Hazelcast utilisez-vous? –

+0

Hazelcast 3.6.7 intégré dans Spring Boot 1.4.5 –

Répondre

0

Enfin je réalisais que je dois injecter l'objet « UserTransactionManager » et prendre la transaction de celui-ci.

Il est également nécessaire d'utiliser une implémentation JTA/XA. J'ai choisi Atomikos et les transactions XA doivent être activées dans MS SQL Server.

L'exemple de travail est disponible sur GitHub https://github.com/diegocairone/hazelcast-maps-poc sur la branche atomikos-datasource-MSSQL

0

A partir de Hazelcast 3.7, vous pouvez vous débarrasser du code passe-partout pour commencer, commettre ou transactions rollback en utilisant HazelcastTransactionManager qui est un PlatformTransactionManager implémentation à utiliser avec Spring Transaction API. Vous pouvez trouver l'exemple here.

De plus, Hazelcast peut participer à une transaction XA avec Atomikos. Here's a doc

Merci

+0

J'ai mis à jour vers Hazelcast 3.7.5 mais j'ai toujours des problèmes avec l'intégration atomikos et Hazelcast ManagedTransactionalTaskContext. Pourriez-vous me donner un coup de main avec ça? Je posterai plus de détails en guise de réponse. –

0

J'avoir mis à jour à Hazelcast 3.7.5 et a ajouté le code suivant à la classe 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; 
} 

Quand je lance l'application je reçois cette exception:

org.springframework.beans.factory.NoSuchBeanDefinitionException: Non haricot nommé 'transactionManager' disponible: Aucun correspondant haricot de PlatformTransactionManager trouvé pour qualifier 'transactionManager' - ni correspondance qualificative ni nom de bean ne correspondent!

Le code est disponible sur GitHub sur une nouvelle branche: atomikos-datasource-MSSQL-hz37

Merci à l'avance

+0

Avez-vous un noisetier dans la classe? –

+0

Oui. Il est déclaré dans pom.xml –