2010-12-08 17 views
4

Nous avons un projet mixte Java et Scala, qui utilise la gestion des transactions Spring. Nous utilisons les aspects de Spring pour tisser les fichiers avec des méthodes annotées @Transactional.Utiliser Spring @Transactional dans Scala

Le problème est que les classes Scala ne sont pas tissées avec les aspects de la transaction Spring. Comment est-ce que je peux configurer Spring pour considérer la transaction dans Scala?

+0

Une solution simple (ou solution de contournement) peuvent être de mettre les annotations sur les interfaces Java et faites votre Les classes Scala implémentent ces interfaces. –

+0

Cela n'est pas possible si vous utilisez Spring Aspects pour tisser les transactions. La transaction n'est pas lancée si l'annotation est à l'interface. – timomeinen

Répondre

3

Le printemps a besoin de votre limite de transaction pour commencer avec les beans gérés par Spring, ce qui exclut @Transactional classes Scala.

Il semble que la solution simple consiste à créer des façades de service @Transactional Java classes instanciées en tant que beans Spring. Ceux-ci peuvent déléguer à votre service Scala/code de base.

2

Une solution Scala uniquement consiste à utiliser la fermeture d'Eberhard Wolff qui crée une transaction manuelle. Utilisation:

transactional() { 
// do stuff in transaction 
} 

https://github.com/ewolff/scala-spring/blob/master/src/main/scala/de/adesso/scalaspring/tx/TransactionManagement.scala

https://github.com/ewolff/scala-spring/blob/master/src/main/scala/de/adesso/scalaspring/tx/TransactionAttributeWithRollbackRules.scala

trouvés ici: http://www.slideshare.net/ewolff/scala-and-spring (slide 41)

Licence: Apache

1

Il n'y a rien de spécial sur le soutien du printemps @Transactional à Scala et vous peut l'utiliser sans aucun code Java. Assurez-vous simplement que vous avez des traits «purs» pour les beans, dont les implémentations utiliseraient l'annotation @Transactional. Vous devez également déclarer un bean avec le type PlatformTransactionManager (si vous utilisez la configuration Spring basée sur .xml, vous devez utiliser "transactionManager" pour le nom du bean, voir EnableTransactionManagement's JavaDoc pour plus de détails). En outre, si vous utilisez des classes de configuration basées sur des annotations, assurez-vous que ces classes sont placées dans leurs propres fichiers dédiés, c'est-à-dire ne placez aucune autre classe (l'objet compagnon est OK) dans le même fichier. Voici exemple de travail simple:

SomeService.scala:

trait SomeService { 
    def someMethod() 
} 

// it is safe to place impl in the same file, but still avoid doing it 
class SomeServiceImpl extends SomeService { 
    @Transactional 
    def someMethod() { 
    // method body will be executed in transactional context 
    } 
} 

AppConfiguration.scala:

@Configuration 
@EnableTransactionManagement 
class AppConfiguration { 
    @Bean 
    def transactionManager(): PlatformTransactionManager = { 
    // bean with PlatformTransactionManager type is required 
    } 

    @Bean 
    def someService(): SomeService = { 
    // someService bean will be proxied with transaction support 
    new SomeServiceImpl 
    } 
} 

// companion object is OK here 
object AppConfiguration { 
    // maybe some helper methods 
} 

// but DO NOT place any other trait/class/object in this file, otherwise Spring will behave incorrectly!