Local transactions support
--------------------------

                 Key: JCR-1446
                 URL: https://issues.apache.org/jira/browse/JCR-1446
             Project: Jackrabbit
          Issue Type: Improvement
          Components: jackrabbit-jca
    Affects Versions: 1.5
            Reporter: Stephane Landelle


JCAManagedConnectionFactory doesn't currently support LocalTransaction. 
Wouldn't it be simple to provide a simple implemetation like the following 
(inspired of JR test suite):
package com.weka.jackrabbit.jca;

import javax.jcr.Session;
import javax.resource.ResourceException;
import javax.resource.spi.LocalTransaction;
import javax.transaction.xa.XAException;
import javax.transaction.xa.XAResource;
import javax.transaction.xa.Xid;

import org.apache.jackrabbit.api.XASession;

/**
 * JackRabbit Local transaction (based on the XA Resource returned by
 * JackRabbit). <p/> Inspired from JackRabbit test suite.
 * 
 * Internal [EMAIL PROTECTED] javax.transaction.LocalTransaction} 
implementation.
 * 
 */
public class JackRabbitLocalTransaction implements LocalTransaction {

        /**
         * Global transaction id counter. TODO: remove the static attribute
         */
        private static byte counter = 0;

        /**
         * XASession
         */
        private XASession session;

        /**
         * XAResource
         */
        private final XAResource xares;

        /**
         * Xid
         */
        private Xid xid;

        /**
         * Create a new instance of this class. Takes a session as parameter.
         * 
         * @param session
         *            session. If session is not of type [EMAIL PROTECTED] 
XASession}, an
         *            <code>IllegalArgumentException</code> is thrown
         */
        public JackRabbitLocalTransaction(Session session) {
                if (session instanceof XASession) {
                        this.session = (XASession) session;
                        xares = this.session.getXAResource();
                } else {
                        throw new IllegalArgumentException("Session not of type 
XASession");
                }
        }

        /**
         * @see javax.transaction.LocalTransaction#begin
         */
        public void begin() throws ResourceException {

                try {
                        xid = new XidImpl(counter++);
                        xares.start(xid, XAResource.TMNOFLAGS);

                } catch (XAException e) {
                        throw new ResourceException("Unable to begin 
transaction: " + "XA_ERR=" + e.errorCode);
                }
        }

        /**
         * @see javax.transaction.LocalTransaction#commit
         */
        public void commit() throws ResourceException {

                try {
                        xares.end(xid, XAResource.TMSUCCESS);
                        xares.prepare(xid);
                        xares.commit(xid, false);
                        session.logout();

                } catch (XAException e) {

                        if (e.errorCode >= XAException.XA_RBBASE && e.errorCode 
<= XAException.XA_RBEND) {
                                throw new ResourceException(e.toString());
                        }

                        throw new ResourceException("Unable to commit 
transaction: " + "XA_ERR=" + e.errorCode);
                }
        }

        /**
         * @see javax.transaction.LocalTransaction#rollback
         */
        public void rollback() throws ResourceException {

                try {
                        xares.end(xid, XAResource.TMFAIL);
                        xares.rollback(xid);
                        session.logout();

                } catch (XAException e) {

                        throw new ResourceException("Unable to rollback 
transaction: " + "XA_ERR=" + e.errorCode);
                }
        }

        /**
         * Internal [EMAIL PROTECTED] Xid} implementation.
         */
        class XidImpl implements Xid {

                /** Global transaction id */
                private final byte[] globalTxId;

                /**
                 * Create a new instance of this class. Takes a global 
transaction
                 * number as parameter
                 * 
                 * @param globalTxNumber
                 *            global transaction number
                 */
                public XidImpl(byte globalTxNumber) {
                        this.globalTxId = new byte[] { globalTxNumber };
                }

                /**
                 * @see javax.transaction.xa.Xid#getFormatId()
                 */
                public int getFormatId() {
                        return 0;
                }

                /**
                 * @see javax.transaction.xa.Xid#getBranchQualifier()
                 */
                public byte[] getBranchQualifier() {
                        return new byte[0];
                }

                /**
                 * @see javax.transaction.xa.Xid#getGlobalTransactionId()
                 */
                public byte[] getGlobalTransactionId() {
                        return globalTxId;
                }
        }

        /**
         * @return Returns the counter.
         */
        public byte getCounter() {
                return counter;
        }

        /**
         * @param counter
         *            The counter to set.
         */
        public void setCounter(byte counter) {
                JackRabbitLocalTransaction.counter = counter;
        }
}


-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to