jackrabbit-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Stephane Landelle (JIRA)" <j...@apache.org>
Subject [jira] Created: (JCR-1446) Local transactions support
Date Mon, 03 Mar 2008 10:38:50 GMT
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 {@link 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 {@link 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 {@link 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.


Mime
View raw message