Communardo Software GmbH, Kleiststraße 10 a, D-01129 Dresden
0800 1 255 255

Transactions mit dem Atlassian PluginFramework

Auch bei der Pluginentwicklung für Confluence kommt irgend­wann der Zeitpunkt, an dem man sich mit kom­ple­xe­ren Abläufen bei der Persistierung von Daten beschäf­ti­gen muss. Um die Integrität die­ser Daten sicher­stel­len zu kön­nen, ist man dann auf den Einsatz von Transactions ange­wie­sen. Da Confluence das Spring Framework ver­wen­det, bie­tet sich hier­für die Nutzung des TransactionTemplate an. Dieses ermög­licht es, wie in der Spring Dokumentation beschrie­ben, auf ein­fa­che Weise kri­ti­schen Code unter Verwendung eines Callbacks in eine Transaction zu ver­pa­cken. Dazu benö­tigt man jedoch noch einen PlatformTransactionManager. Dieser imple­men­tiert die Strategie für die Transaktionsbehandlung, die im Fall von Confluence auf Hibernate basiert. Auch hierzu kön­nen wei­tere Informationen und ein Codebeispiel auf den Seiten von Spring gefun­den wer­den. Der PlatformTransactionManager ist als Bean im Application Context von Confluence vor­han­den und kann über den ComponentContainer refe­ren­ziert werden:

public PlatformTransactionManager getTransactionManager(){
    return (PlatformTransactionManager) ComponentContainer.get("transactionManager");
}

Allerdings funk­tio­niert die­ses Codebeispiel nach einer Umstellung auf V2-Plugins nicht mehr. Der Grund: Da diese Plugins in OSGI-Bundles umge­wan­delt wer­den, wel­che eine andere Spring Version ver­wen­den als die Kern-Applikation, kommt es bei der Referenzierung der transactionManager-Bean über den ComponentContainer zu einer ClassCastException.

Bei der Suche nach einer Lösung für die­ses Problem bin ich über ein Ticket im Issue Tracker von Atlassian gestol­pert, in des­sen Kommentaren eine Alternative beschrie­ben wird: Abhilfe schafft die Verwendung der Shared Access Layer (SAL), einer ein­heit­li­chen Service-Schicht für alle Atlassian Anwendungen. Sie stellt neben ver­schie­den ande­ren Services auch ein TransactionTemplate bereit, das für Confluence bereits den auf Hibernate basie­ren­den PlatformTransactionManager gesetzt hat und auf fol­gende Weise refe­ren­ziert wer­den kann.

Zunächst muss das Template als Komponente (Spring-Bean) im Plugin-Descriptor (atlassian-plugin.xml) impor­tiert werden:

<component-import name="SAL Transaction Template" key="salTransactionTemplate">
    <interface>com.atlassian.sal.api.transaction.TransactionTemplate</interface>
</component-import>

Dann kann man sich die Komponente per Spring Autowiring in fast alle Plugin Modultypen (z. B. Actions und Components ) inji­zie­ren las­sen. Der Name der zu inji­zie­ren­den Bean ent­spricht dem Key des component-import Elementes im Plugin-Descriptor (in die­sem Beispiel also "salTransactionTemplate" ):

public void setSalTransactionTemplate(TransactionTemplate template){
    this.transactionTemplate = template;
}

Nun kann das Template wie  oben beschrie­ben ver­wen­det werden.

Noch ein Hinweis: SAL wird erst ab Confluence 3.0 mit aus­ge­lie­fert. Für Confluence 2.10 muss man also eine andere Lösung finden.

&lt;

Related Posts

1 Kommentar

Avatar Michael Rieger

Die hier skiz­zierte Lösung funk­tio­niert lei­der nicht für Job Plugin Komponenten, da deren Abhängigkeiten nicht von Spring erfüllt wer­den und damit das SAL TransactionTemplate dort nicht zur Verfügung steht.
Für eine Lösung des Problem im Rahmen von Jobs, vgl.:
http://forums.atlassian.com/thread.jspa?messageID=257346003&#257346003

Comments are closed.

Pin It on Pinterest