Java tutorial
/** * Copyright 2011 meltmedia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.xchain.namespaces.jta; import org.apache.commons.jxpath.JXPathContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.xchain.annotations.Attribute; import org.xchain.annotations.AttributeType; import org.xchain.annotations.Element; import org.xchain.framework.jxpath.ScopedQNameVariables; import org.xchain.framework.jxpath.Scope; import org.xchain.framework.lifecycle.ContainerContext; import org.xchain.impl.ChainImpl; import javax.transaction.UserTransaction; import javax.transaction.Status; import javax.xml.namespace.QName; /** * Demarcate the bounds of a JTA UserTransaction * * <code class="source"> * <jta:transaction xmlns:jta="http://www.xchain.org/jta/1.0" timeout="90"/> * </code> * * @author Mike Moulton * @author Christian Trimble * @author Josh Kennedy * @author John Trimble */ @Element(localName = "transaction") public abstract class TransactionCommand extends ChainImpl { public static Logger log = LoggerFactory.getLogger(TransactionCommand.class); /** * The transaction timeout */ @Attribute(localName = "timeout", type = AttributeType.JXPATH_VALUE, defaultValue = "'90'") public abstract Integer getTimeout(JXPathContext context); @Attribute(localName = "result", type = AttributeType.QNAME, defaultValue = "{" + Constants.URI + "}" + Constants.USER_TRANSACTION) public abstract QName getResult(JXPathContext context); public boolean execute(JXPathContext context) throws Exception { boolean managingTransaction = false; boolean result = false; UserTransaction transaction = ContainerContext.getJtaLookupStrategy().getUserTransaction(); if (transaction != null) { try { // if there is not a transaction running, then start one. if (Status.STATUS_ACTIVE != transaction.getStatus()) { managingTransaction = true; transaction.setTransactionTimeout(this.getTimeout(context)); transaction.begin(); } // put the transaction into the context. ((ScopedQNameVariables) context.getVariables()).declareVariable(getResult(context), transaction, Scope.execution); // execute the chain result = super.execute(context); // roll back the transaction. if (managingTransaction) { transaction.commit(); } } catch (Exception e) { if (managingTransaction) { if (transaction.getStatus() != Status.STATUS_NO_TRANSACTION) { transaction.rollback(); } } throw e; } finally { // TODO: If we defined the transaction variable, then we should remove it. } } else { // TODO: Should this throw an IllegalStateException? Returning true seems like the wrong behavior. result = true; } return result; } }