Skip to content

Commit

Permalink
Async transaction API
Browse files Browse the repository at this point in the history
  • Loading branch information
nmcl committed May 4, 2015
1 parent 3e9940c commit 266a675
Show file tree
Hide file tree
Showing 5 changed files with 486 additions and 0 deletions.
227 changes: 227 additions & 0 deletions STM/src/main/java/org/jboss/stm/async/Transaction.java
@@ -0,0 +1,227 @@
/*
* JBoss, Home of Professional Open Source
* Copyright 2006, Red Hat Middleware LLC, and individual contributors
* as indicated by the @author tags.
* See the copyright.txt in the distribution for a
* full listing of individual contributors.
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License, v. 2.1.
* This program is distributed in the hope that it will be useful, but WITHOUT A
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public License,
* v.2.1 along with this distribution; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
* (C) 2015,
* @author JBoss Inc.
*/


package org.jboss.stm.async;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import org.jboss.stm.internal.async.TransactionExecutorAbort;
import org.jboss.stm.internal.async.TransactionExecutorBegin;
import org.jboss.stm.internal.async.TransactionExecutorCommit;

import com.arjuna.ats.arjuna.AtomicAction;
import com.arjuna.ats.arjuna.common.Uid;

/**
* This is a user-level transaction class. Unlike AtomicAction which it uses, this
* provides an asynchronous begin, commit and rollback capability. There
* are a number of ways in which we currently support asynchronous interactions with
* the transaction system, such as async prepare or async commit. The developer could
* also register a two-phase aware participant or a Synchronisation and use callbacks
* themselves to determine the outcome of the transaction. These continue to be
* available to the developer but this API is intended to provide a simplified interface
* to allow clients to make use of asynchronous transactions.
*
* Note, we deliberately don't derive from AtomicAction so that developers must make
* a conscious choice between a synchronous or asynchronous transaction.
*
* @author Mark Little (mark@arjuna.com)
* @version $Id$
*/

public class Transaction
{
/**
* Create a new transaction. If there is already a transaction associated
* with the thread then this new transaction will be automatically nested.
* The transaction is *not* running at this point.
*
* No timeout is associated with this transaction, i.e., it will not be
* automatically rolled back by the system.
*/

public Transaction ()
{
_theTransaction = new AtomicAction();
}

/**
* AtomicAction constructor with a Uid. This constructor is for recreating
* an AtomicAction, typically during crash recovery.
*/

public Transaction (Uid objUid)
{
_theTransaction = new AtomicAction(objUid);
}

/**
* Start the transaction running.
*
* If the transaction is already running or has terminated, then an error
* code will be returned. No timeout is associated with the transaction.
*
* @return <code>ActionStatus</code> indicating outcome.
*/

public Future<Integer> begin ()
{
return begin(AtomicAction.NO_TIMEOUT);
}

/**
* Start the transaction running.
*
* If the transaction is already running or has terminated, then an error
* code will be returned.
*
* @param timeout the timeout associated with the transaction. If the
* transaction is still active when this timeout elapses, the
* system will automatically roll it back.
*
* @return <code>ActionStatus</code> indicating outcome.
*/

public Future<Integer> begin (int timeout)
{
return _threadPool.submit(new TransactionExecutorBegin(timeout, _theTransaction));
}

/**
* Commit the transaction, and have heuristic reporting. Heuristic reporting
* via the return code is enabled.
*
* @return <code>ActionStatus</code> indicating outcome.
*/

public Future<Integer> commit ()
{
return commit(true);
}

/**
* Commit the transaction. The report_heuristics parameter can be used to
* determine whether or not heuristic outcomes are reported.
*
* If the transaction has already terminated, or has not begun, then an
* appropriate error code will be returned.
*
* @return <code>ActionStatus</code> indicating outcome.
*/

public Future<Integer> commit (boolean report_heuristics)
{
return _threadPool.submit(new TransactionExecutorCommit(report_heuristics, _theTransaction));
}

/**
* Abort (rollback) the transaction.
*
* If the transaction has already terminated, or has not been begun, then an
* appropriate error code will be returned.
*
* @return <code>ActionStatus</code> indicating outcome.
*/

public Future<Integer> abort ()
{
return _threadPool.submit(new TransactionExecutorAbort(_theTransaction));
}

/*
* @return the timeout associated with this instance.
*/

public final int getTimeout ()
{
return _theTransaction.getTimeout();
}

/**
* The type of the class is used to locate the state of the transaction log
* in the object store.
*
* Overloads BasicAction.type()
*
* @return a string representation of the hierarchy of the class for storing
* logs in the transaction object store.
*/

public String type ()
{
return _theTransaction.type();
}

/**
* Suspend all transaction association from the invoking thread. When this
* operation returns, the thread will be associated with no transactions.
*
* If the current transaction is not an AtomicAction then this method will
* not suspend.
*
* Note, we do not provide an async version of suspend because it would be
* wrong for an application thread to proceed under the assumption it had
* succeeded/happened yet. Ordering of events makes a difference here.
*
* @return a handle on the current AtomicAction (if any) so that the thread
* can later resume association if required.
*
*/

public static final Transaction suspend ()
{
return new Transaction(AtomicAction.suspend());
}

/**
* Resume transaction association on the current thread. If the specified
* transaction is null, then this is the same as doing a suspend. If the
* current thread is associated with transactions then those associations
* will be lost.
*
* Note, we do not provide an async version of resume because it would be
* wrong for an application thread to proceed under the assumption it had
* succeeded/happened yet. Ordering of events makes a difference here.
*
* @param act the transaction to associate. If this is a nested
* transaction, then the thread will be associated with all of
* the transactions in the hierarchy.
*
* @return <code>true</code> if association is successful,
* <code>false</code> otherwise.
*/

public static final boolean resume (Transaction act)
{
return AtomicAction.resume(act._theTransaction);
}

private Transaction (AtomicAction act)
{
_theTransaction = act;
}

private AtomicAction _theTransaction;
private final ExecutorService _threadPool = Executors.newFixedThreadPool(1);
}
@@ -0,0 +1,51 @@
/*
* JBoss, Home of Professional Open Source
* Copyright 2006, JBoss Inc., and individual contributors as indicated
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/

package org.jboss.stm.internal.async;

import java.util.concurrent.Callable;

import com.arjuna.ats.arjuna.AtomicAction;


/**
* Executes the transaction.
*
* @author marklittle
*
*/

public class TransactionExecutorAbort implements Callable<Integer>
{
public TransactionExecutorAbort (AtomicAction tx)
{
_theTransaction = tx;
}

@Override
public Integer call () throws Exception
{
return new Integer(_theTransaction.abort());
}

private AtomicAction _theTransaction;
}
@@ -0,0 +1,53 @@
/*
* JBoss, Home of Professional Open Source
* Copyright 2006, JBoss Inc., and individual contributors as indicated
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/

package org.jboss.stm.internal.async;

import java.util.concurrent.Callable;

import com.arjuna.ats.arjuna.AtomicAction;


/**
* Executes the transaction.
*
* @author marklittle
*
*/

public class TransactionExecutorBegin implements Callable<Integer>
{
public TransactionExecutorBegin (int timeout, AtomicAction tx)
{
_timeout = timeout;
_theTransaction = tx;
}

@Override
public Integer call () throws Exception
{
return new Integer(_theTransaction.begin(_timeout));
}

private int _timeout;
private AtomicAction _theTransaction;
}
@@ -0,0 +1,53 @@
/*
* JBoss, Home of Professional Open Source
* Copyright 2006, JBoss Inc., and individual contributors as indicated
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/

package org.jboss.stm.internal.async;

import java.util.concurrent.Callable;

import com.arjuna.ats.arjuna.AtomicAction;


/**
* Executes the transaction.
*
* @author marklittle
*
*/

public class TransactionExecutorCommit implements Callable<Integer>
{
public TransactionExecutorCommit (boolean reportHeuristics, AtomicAction tx)
{
_heuristics = reportHeuristics;
_theTransaction = tx;
}

@Override
public Integer call () throws Exception
{
return new Integer(_theTransaction.commit(_heuristics));
}

private boolean _heuristics;
private AtomicAction _theTransaction;
}

0 comments on commit 266a675

Please sign in to comment.