/* * Copyright (c) 2020 MarkLogic Corporation */ package com.marklogic.xcc.examples; import java.net.URI; import javax.transaction.TransactionManager; import javax.transaction.xa.XAResource; import com.arjuna.ats.arjuna.recovery.RecoveryManager; import com.arjuna.ats.arjuna.recovery.RecoveryModule; import com.arjuna.ats.jta.recovery.XAResourceRecoveryHelper; import com.arjuna.ats.internal.jta.recovery.arjunacore.XARecoveryModule; import com.marklogic.xcc.AdhocQuery; import com.marklogic.xcc.ContentSource; import com.marklogic.xcc.ContentSourceFactory; import com.marklogic.xcc.ResultSequence; import com.marklogic.xcc.Session; public class XA { public static void main(String[] args) throws Exception { if (args.length != 2) { System.err.println("usage: xcc://user1:password1@host1:port1/contentbase1 xcc://user2:password2@host2:port2/contentbase2"); System.err.println(); System.err.println("Specify two MarkLogic clusters to participate in the distributed transaction."); System.err.println("hint: You can try out XA transactions across two databases in the same MarkLogic cluster"); System.err.println(" by specifying the same host with different contentbases in the two URLs."); return; } final ContentSource cs1 = ContentSourceFactory.newContentSource(new URI(args[0])); final ContentSource cs2 = ContentSourceFactory.newContentSource(new URI(args[1])); // JBoss specific recovery setup RecoveryManager rm = RecoveryManager.manager(); for(RecoveryModule mod : rm.getModules()) { if(mod instanceof XARecoveryModule) { ((XARecoveryModule)mod).addXAResourceRecoveryHelper( new XAResourceRecoveryHelper() { public boolean initialise(String p) throws Exception { return true; } public XAResource[] getXAResources() throws Exception { return new XAResource[] { cs1.newSession().getXAResource(), cs2.newSession().getXAResource() }; } }); break; } } // Force recovery rm.scan(); TransactionManager tm = com.arjuna.ats.jta.TransactionManager.transactionManager(); Session session1 = cs1.newSession(); Session session2 = cs2.newSession(); try { // Begin the distributed transaction tm.begin(); // Enlist the MarkLogic XAResource instances tm.getTransaction().enlistResource(session1.getXAResource()); tm.getTransaction().enlistResource(session2.getXAResource()); // Perform work on the Session instances AdhocQuery req = session1.newAdhocQuery( "xquery version '1.0-ml';\n" + "xdmp:host-status(xdmp:host())//*:transaction\n" + " [*:transaction-id eq xdmp:transaction()],\n" + "xdmp:document-insert('query1', )" ); ResultSequence rs = session1.submitRequest(req); System.out.println(rs.asString(System.getProperty("line.separator"))); rs.close(); req = session2.newAdhocQuery( "xquery version '1.0-ml';\n" + "xdmp:host-status(xdmp:host())//*:transaction\n" + " [*:transaction-id eq xdmp:transaction()],\n" + "xdmp:document-insert('query2', )" ); rs = session2.submitRequest(req); System.out.println(rs.asString(System.getProperty("line.separator"))); rs.close(); // Commit the distributed transaction tm.commit(); } catch(Exception e) { e.printStackTrace(); if(tm.getTransaction() != null) tm.rollback(); } finally { session1.close(); session2.close(); } // JBoss specific recovery termination rm.terminate(); } }