[jboss-cvs] JBossAS SVN: r65813 - in trunk/transaction: src/etc and 8 other directories.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Wed Oct 3 17:45:07 EDT 2007
Author: reverbel
Date: 2007-10-03 17:45:05 -0400 (Wed, 03 Oct 2007)
New Revision: 65813
Removed:
trunk/transaction/build.bat
trunk/transaction/build.sh
trunk/transaction/build.xml
trunk/transaction/component-info.xml
trunk/transaction/jbossbuild.xml
trunk/transaction/pom.xml
trunk/transaction/src/etc/default.mf
trunk/transaction/src/main/org/jboss/tm/CoordinatorFactory.java
trunk/transaction/src/main/org/jboss/tm/GlobalId.java
trunk/transaction/src/main/org/jboss/tm/JBossRollbackException.java
trunk/transaction/src/main/org/jboss/tm/JBossXAException.java
trunk/transaction/src/main/org/jboss/tm/LocalId.java
trunk/transaction/src/main/org/jboss/tm/OTSContextFactory.java
trunk/transaction/src/main/org/jboss/tm/ResourceFactory.java
trunk/transaction/src/main/org/jboss/tm/StringRemoteRefConverter.java
trunk/transaction/src/main/org/jboss/tm/TMUtil.java
trunk/transaction/src/main/org/jboss/tm/TransactionImpl.java
trunk/transaction/src/main/org/jboss/tm/TransactionManagerInitializer.java
trunk/transaction/src/main/org/jboss/tm/TransactionManagerService.java
trunk/transaction/src/main/org/jboss/tm/TransactionManagerServiceMBean.java
trunk/transaction/src/main/org/jboss/tm/TxManager.java
trunk/transaction/src/main/org/jboss/tm/XidFactory.java
trunk/transaction/src/main/org/jboss/tm/XidFactoryBase.java
trunk/transaction/src/main/org/jboss/tm/XidFactoryImpl.java
trunk/transaction/src/main/org/jboss/tm/XidFactoryMBean.java
trunk/transaction/src/main/org/jboss/tm/XidImpl.java
trunk/transaction/src/main/org/jboss/tm/integrity/AbstractTransactionIntegrity.java
trunk/transaction/src/main/org/jboss/tm/integrity/FailIncompleteTransaction.java
trunk/transaction/src/main/org/jboss/tm/integrity/FailIncompleteTransactionIntegrity.java
trunk/transaction/src/main/org/jboss/tm/integrity/FailIncompleteTransactionMBean.java
trunk/transaction/src/main/org/jboss/tm/integrity/TransactionIntegrity.java
trunk/transaction/src/main/org/jboss/tm/integrity/TransactionIntegrityFactory.java
trunk/transaction/src/main/org/jboss/tm/package.html
trunk/transaction/src/main/org/jboss/tm/recovery/BatchLog.java
trunk/transaction/src/main/org/jboss/tm/recovery/BatchRecoveryLogReader.java
trunk/transaction/src/main/org/jboss/tm/recovery/BatchRecoveryLogger.java
trunk/transaction/src/main/org/jboss/tm/recovery/BatchRecoveryLoggerService.java
trunk/transaction/src/main/org/jboss/tm/recovery/BatchRecoveryLoggerServiceMBean.java
trunk/transaction/src/main/org/jboss/tm/recovery/BatchWriter.java
trunk/transaction/src/main/org/jboss/tm/recovery/CorruptedLogRecordException.java
trunk/transaction/src/main/org/jboss/tm/recovery/HeuristicStatus.java
trunk/transaction/src/main/org/jboss/tm/recovery/HeuristicStatusLog.java
trunk/transaction/src/main/org/jboss/tm/recovery/HeuristicStatusLogReader.java
trunk/transaction/src/main/org/jboss/tm/recovery/HexDump.java
trunk/transaction/src/main/org/jboss/tm/recovery/LogRecord.java
trunk/transaction/src/main/org/jboss/tm/recovery/LogRestarter.java
trunk/transaction/src/main/org/jboss/tm/recovery/PendingWriteRequest.java
trunk/transaction/src/main/org/jboss/tm/recovery/Recoverable.java
trunk/transaction/src/main/org/jboss/tm/recovery/RecoveryLogReader.java
trunk/transaction/src/main/org/jboss/tm/recovery/RecoveryLogger.java
trunk/transaction/src/main/org/jboss/tm/recovery/RecoveryLoggerInstance.java
trunk/transaction/src/main/org/jboss/tm/recovery/RecoveryManager.java
trunk/transaction/src/main/org/jboss/tm/recovery/RecoveryManagerService.java
trunk/transaction/src/main/org/jboss/tm/recovery/RecoveryManagerServiceMBean.java
trunk/transaction/src/main/org/jboss/tm/recovery/RecoveryTestingException.java
trunk/transaction/src/main/org/jboss/tm/recovery/SimpleHeuristicStatusLogReader.java
trunk/transaction/src/main/org/jboss/tm/recovery/TransactionCompletionLogger.java
trunk/transaction/src/main/org/jboss/tm/recovery/TxCompletionHandler.java
trunk/transaction/src/main/org/jboss/tm/recovery/XAResourceAccess.java
trunk/transaction/src/main/org/jboss/tm/recovery/XAWork.java
trunk/transaction/src/main/org/jboss/tm/recovery/XidFactoryInitializationService.java
trunk/transaction/src/main/org/jboss/tm/recovery/XidFactoryInitializationServiceMBean.java
trunk/transaction/src/main/org/jboss/tm/recovery/test/TestForceTime.java
trunk/transaction/src/main/org/jboss/tm/recovery/test/TestOracleXA.java
trunk/transaction/src/main/org/jboss/tm/remoting/ClientInvocationHandler.java
trunk/transaction/src/main/org/jboss/tm/remoting/Invocation.java
trunk/transaction/src/main/org/jboss/tm/remoting/RemoteProxy.java
trunk/transaction/src/main/org/jboss/tm/remoting/client/ClientUserTransaction.java
trunk/transaction/src/main/org/jboss/tm/remoting/client/ClientUserTransactionObjectFactory.java
trunk/transaction/src/main/org/jboss/tm/remoting/interfaces/Coordinator.java
trunk/transaction/src/main/org/jboss/tm/remoting/interfaces/HeuristicHazardException.java
trunk/transaction/src/main/org/jboss/tm/remoting/interfaces/RecoveryCoordinator.java
trunk/transaction/src/main/org/jboss/tm/remoting/interfaces/Resource.java
trunk/transaction/src/main/org/jboss/tm/remoting/interfaces/Status.java
trunk/transaction/src/main/org/jboss/tm/remoting/interfaces/Synchronization.java
trunk/transaction/src/main/org/jboss/tm/remoting/interfaces/SynchronizationUnavailableException.java
trunk/transaction/src/main/org/jboss/tm/remoting/interfaces/Terminator.java
trunk/transaction/src/main/org/jboss/tm/remoting/interfaces/TransactionAlreadyPreparedException.java
trunk/transaction/src/main/org/jboss/tm/remoting/interfaces/TransactionFactory.java
trunk/transaction/src/main/org/jboss/tm/remoting/interfaces/TransactionInactiveException.java
trunk/transaction/src/main/org/jboss/tm/remoting/interfaces/TransactionNotPreparedException.java
trunk/transaction/src/main/org/jboss/tm/remoting/interfaces/TxPropagationContext.java
trunk/transaction/src/main/org/jboss/tm/remoting/interfaces/Vote.java
trunk/transaction/src/main/org/jboss/tm/remoting/server/DTMInvocationHandler.java
trunk/transaction/src/main/org/jboss/tm/remoting/server/DTMServant.java
trunk/transaction/src/main/org/jboss/tm/remoting/server/DistributedTransactionManager.java
trunk/transaction/src/main/org/jboss/tm/remoting/server/DistributedTransactionManagerMBean.java
Log:
Delete TM/OTS/DTM code, which now lives in a separate project (at http://xactor.sourceforge.net).
Deleted: trunk/transaction/build.bat
===================================================================
--- trunk/transaction/build.bat 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/build.bat 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,89 +0,0 @@
- at echo off
-REM ======================================================================
-REM
-REM This is the main entry point for the build system.
-REM
-REM Users should be sure to execute this file rather than 'ant' to ensure
-REM the correct version is being used with the correct configuration.
-REM
-REM ======================================================================
-REM
-REM $Id$
-REM
-REM Authors:
-REM Jason Dillon <jason at planet57.com>
-REM Sacha Labourey <sacha.labourey at cogito-info.ch>
-REM
-
-REM ******************************************************
-REM Ignore the ANT_HOME variable: we want to use *our*
-REM ANT version and associated JARs.
-REM ******************************************************
-REM Ignore the users classpath, cause it might mess
-REM things up
-REM ******************************************************
-
-SETLOCAL
-
-set CLASSPATH=
-set ANT_HOME=
-set ANT_OPTS=-Djava.protocol.handler.pkgs=org.jboss.net.protocol -Dbuild.script=build.bat
-
-REM ******************************************************
-REM - "for" loops have been unrolled for compatibility
-REM with some WIN32 systems.
-REM ******************************************************
-
-set NAMES=tools;tools\ant;tools\apache\ant
-set SUBFOLDERS=..;..\..;..\..\..;..\..\..\..
-
-REM ******************************************************
-REM ******************************************************
-
-SET EXECUTED=FALSE
-for %%i in (%NAMES%) do call :subLoop %%i %1 %2 %3 %4 %5 %6
-
-goto :EOF
-
-
-REM ******************************************************
-REM ********* Search for names in the subfolders *********
-REM ******************************************************
-
-:subLoop
-for %%j in (%SUBFOLDERS%) do call :testIfExists %%j\%1\bin\ant.bat %2 %3 %4 %5 %6 %7
-
-goto :EOF
-
-
-REM ******************************************************
-REM ************ Test if ANT Batch file exists ***********
-REM ******************************************************
-
-:testIfExists
-if exist %1 call :BatchFound %1 %2 %3 %4 %5 %6 %7 %8
-
-goto :EOF
-
-
-REM ******************************************************
-REM ************** Batch file has been found *************
-REM ******************************************************
-
-:BatchFound
-if (%EXECUTED%)==(FALSE) call :ExecuteBatch %1 %2 %3 %4 %5 %6 %7 %8
-set EXECUTED=TRUE
-
-goto :EOF
-
-REM ******************************************************
-REM ************* Execute Batch file only once ***********
-REM ******************************************************
-
-:ExecuteBatch
-echo Calling %1 %2 %3 %4 %5 %6 %7 %8
-call %1 %2 %3 %4 %5 %6 %7 %8
-
-:end
-
-if "%NOPAUSE%" == "" pause
Deleted: trunk/transaction/build.sh
===================================================================
--- trunk/transaction/build.sh 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/build.sh 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,172 +0,0 @@
-#!/bin/sh
-### ====================================================================== ###
-## ##
-## This is the main entry point for the build system. ##
-## ##
-## Users should be sure to execute this file rather than 'ant' to ensure ##
-## the correct version is being used with the correct configuration. ##
-## ##
-### ====================================================================== ###
-
-# $Id$
-
-PROGNAME=`basename $0`
-DIRNAME=`dirname $0`
-GREP="grep"
-ROOT="/"
-
-# Ignore user's ANT_HOME if it is set
-ANT_HOME=""
-
-# the default search path for ant
-ANT_SEARCH_PATH="\
- tools
- tools/ant \
- tools/apache/ant \
- ant"
-
-# the default build file name
-ANT_BUILD_FILE="build.xml"
-
-# the default arguments
-ANT_OPTIONS="-find $ANT_BUILD_FILE"
-
-# Use the maximum available, or set MAX_FD != -1 to use that
-MAX_FD="maximum"
-
-# OS specific support (must be 'true' or 'false').
-cygwin=false;
-darwin=false;
-case "`uname`" in
- CYGWIN*)
- cygwin=true
- ;;
-
- Darwin*)
- darwin=true
- ;;
-esac
-
-#
-# Helper to complain.
-#
-die() {
- echo "${PROGNAME}: $*"
- exit 1
-}
-
-#
-# Helper to complain.
-#
-warn() {
- echo "${PROGNAME}: $*"
-}
-
-#
-# Helper to source a file if it exists.
-#
-maybe_source() {
- for file in $*; do
- if [ -f "$file" ]; then
- . $file
- fi
- done
-}
-
-search() {
- search="$*"
- for d in $search; do
- ANT_HOME="`pwd`/$d"
- ANT="$ANT_HOME/bin/ant"
- if [ -x "$ANT" ]; then
- # found one
- echo $ANT_HOME
- break
- fi
- done
-}
-
-#
-# Main function.
-#
-main() {
- # if there is a build config file. then source it
- maybe_source "$DIRNAME/build.conf" "$HOME/.build.conf"
-
- # Increase the maximum file descriptors if we can
- if [ $cygwin = "false" ]; then
- MAX_FD_LIMIT=`ulimit -H -n`
- if [ $? -eq 0 ]; then
- if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ]; then
- # use the system max
- MAX_FD="$MAX_FD_LIMIT"
- fi
-
- ulimit -n $MAX_FD
- if [ $? -ne 0 ]; then
- warn "Could not set maximum file descriptor limit: $MAX_FD"
- fi
- else
- warn "Could not query system maximum file descriptor limit: $MAX_FD_LIMIT"
- fi
- fi
-
- # try the search path
- ANT_HOME=`search $ANT_SEARCH_PATH`
-
- # try looking up to root
- if [ "x$ANT_HOME" = "x" ]; then
- target="build"
- _cwd=`pwd`
-
- while [ "x$ANT_HOME" = "x" ] && [ "$cwd" != "$ROOT" ]; do
- cd ..
- cwd=`pwd`
- ANT_HOME=`search $ANT_SEARCH_PATH`
- done
-
- # make sure we get back
- cd $_cwd
-
- if [ "$cwd" != "$ROOT" ]; then
- found="true"
- fi
-
- # complain if we did not find anything
- if [ "$found" != "true" ]; then
- die "Could not locate Ant; check \$ANT or \$ANT_HOME."
- fi
- fi
-
- # make sure we have one
- ANT=$ANT_HOME/bin/ant
- if [ ! -x "$ANT" ]; then
- die "Ant file is not executable: $ANT"
- fi
-
- # need to specify planet57/buildmagic protocol handler package
- ANT_OPTS="-Djava.protocol.handler.pkgs=org.jboss.net.protocol"
-
- # setup some build properties
- ANT_OPTS="$ANT_OPTS -Dbuild.script=$0"
-
- # change to the directory where the script lives so users are not forced
- # to be in the same directory as build.xml
- cd $DIRNAME
-
- # export some stuff for ant
- export ANT ANT_HOME ANT_OPTS
-
- # execute in debug mode, or simply execute
- if [ "x$ANT_DEBUG" != "x" ]; then
- /bin/sh -x $ANT $ANT_OPTIONS "$@"
- else
- exec $ANT $ANT_OPTIONS "$@"
- fi
-}
-
-##
-## Bootstrap
-##
-
-main "$@"
Deleted: trunk/transaction/build.xml
===================================================================
--- trunk/transaction/build.xml 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/build.xml 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,333 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE project [
- <!ENTITY buildmagic SYSTEM "../tools/etc/buildmagic/buildmagic.ent">
- <!ENTITY libraries SYSTEM "../thirdparty/libraries.ent">
- <!ENTITY modules SYSTEM "../tools/etc/buildmagic/modules.ent">
-]>
-
-<!-- ====================================================================== -->
-<!-- -->
-<!-- JBoss, the OpenSource J2EE webOS -->
-<!-- -->
-<!-- Distributable under LGPL license. -->
-<!-- See terms of license at http://www.gnu.org. -->
-<!-- -->
-<!-- ====================================================================== -->
-
-<!-- $Id$ -->
-
-<project default="main" name="JBoss/Transaction">
-
- <!-- ================================================================== -->
- <!-- Setup -->
- <!-- ================================================================== -->
-
- <!--
- | Include the common Buildmagic elements.
- |
- | This defines several different targets, properties and paths.
- | It also sets up the basic extention tasks amoung other things.
- -->
-
- &buildmagic;
-
-
- <!-- ================================================================== -->
- <!-- Initialization -->
- <!-- ================================================================== -->
-
- <!--
- | Initialize the build system. Must depend on '_buildmagic:init'.
- | Other targets should depend on 'init' or things will mysteriously fail.
- -->
-
- <target name="init" unless="init.disable" depends="_buildmagic:init">
- </target>
-
-
- <!-- ================================================================== -->
- <!-- Configuration -->
- <!-- ================================================================== -->
-
- <!--
- | Configure the build system.
- |
- | This target is invoked by the Buildmagic initialization logic and
- | should contain module specific configuration elements.
- -->
-
- <target name="configure" unless="configure.disable">
-
- <!-- =================== -->
- <!-- Basic Configuration -->
- <!-- =================== -->
-
- <!-- Module name(s) & version -->
- <property name="module.name" value="jboss-transaction"/>
- <property name="module.Name" value="JBoss Transaction"/>
- <property name="module.version" value="DEV"/>
-
- <!-- ========= -->
- <!-- Libraries -->
- <!-- ========= -->
- &libraries;
-
- <!-- The combined library classpath -->
- <path id="library.classpath">
- <path refid="apache.log4j.classpath"/>
- <path refid="apache.commons.classpath"/>
- <path refid="oswego.concurrent.classpath"/>
- <path refid="jboss.remoting.classpath"/>
- <path refid="jboss.integration.classpath"/>
- </path>
-
- <!-- ======= -->
- <!-- Modules -->
- <!-- ======= -->
-
- &modules;
-
- <!-- The combined dependent module classpath -->
- <path id="dependentmodule.classpath">
- <path refid="jboss.jboss.javaee.classpath"/>
- <path refid="jboss.common.core.classpath"/>
- <path refid="jboss.common.logging.spi.classpath"/>
- <path refid="jboss.common.logging.log4j.classpath"/>
- <path refid="jboss.common.logging.jdk.classpath"/>
- <path refid="jboss.systemjmx.classpath"/>
- <path refid="jboss.system.classpath"/>
- <path refid="jboss.j2se.classpath"/>
- <path refid="jboss.main.classpath"/>
- </path>
-
- <!-- ===== -->
- <!-- Tasks -->
- <!-- ===== -->
-
- <!-- Where source files live -->
- <property name="source.java" value="${module.source}/main"/>
- <property name="source.etc" value="${module.source}/etc"/>
-
- <!-- Where build generated files will go -->
- <property name="build.reports" value="${module.output}/reports"/>
- <property name="build.classes" value="${module.output}/classes"/>
- <property name="build.lib" value="${module.output}/lib"/>
- <property name="build.api" value="${module.output}/api"/>
- <property name="build.etc" value="${module.output}/etc"/>
- <property name="build.gen-src" value="${module.output}/gen-src"/>
-
- <!-- Install/Release structure -->
- <property name="install.id" value="${module.name}-${module.version}"/>
- <property name="release.id" value="${install.id}"/>
- <property name="install.root" value="${module.output}/${install.id}"/>
-
- <!-- The combined thirdparty classpath -->
- <path id="thirdparty.classpath">
- <path refid="library.classpath"/>
- <path refid="dependentmodule.classpath"/>
- </path>
-
- <!-- classpath and local.classpath must have a value using with a path -->
- <property name="classpath" value=""/>
- <property name="local.classpath" value=""/>
-
- <!-- The classpath required to build classes. -->
- <path id="javac.classpath">
- <pathelement path="${classpath}"/>
- <pathelement path="${local.classpath}"/>
- <path refid="thirdparty.classpath"/>
- </path>
-
- <!-- The classpath required to build javadocs. -->
- <path id="javadoc.classpath">
- <path refid="javac.classpath"/>
- </path>
-
- <!-- Packages to include when generating api documentation -->
- <property name="javadoc.packages" value="org.jboss.*"/>
-
- <!-- Override JUnit defaults -->
- <property name="junit.timeout" value="240000"/> <!-- 4 minutes -->
- <property name="junit.batchtest.todir" value="${build.reports}"/>
- <property name="junit.jvm.options" value="-Ddummy"/>
-
- <!-- xdoclet -->
- <path id="xdoclet.task.classpath">
- <path refid="javac.classpath"/>
- <fileset dir="${xdoclet.xdoclet.lib}">
- <include name="**/*.jar"/>
- </fileset>
- </path>
- <property name="xdoclet.task.classpath" refid="xdoclet.task.classpath"/>
- </target>
-
-
- <!-- ================================================================== -->
- <!-- Compile -->
- <!-- ================================================================== -->
-
- <!--
- | Compile everything.
- |
- | This target should depend on other compile-* targets for each
- | different type of compile that needs to be performed, short of
- | documentation compiles.
- -->
-
- <target name="compile"
- description="Compile all source files."
- depends="compile-classes, compile-etc"/>
-
- <!-- Compile all class files -->
- <target name="compile-classes" depends="init">
- <mkdir dir="${build.classes}"/>
- <javac destdir="${build.classes}"
- optimize="${javac.optimize}"
- target="${javac.target}"
- source="${javac.source}"
- debug="${javac.debug}"
- depend="${javac.depend}"
- verbose="${javac.verbose}"
- deprecation="${javac.deprecation}"
- includeAntRuntime="${javac.include.ant.runtime}"
- includeJavaRuntime="${javac.include.java.runtime}"
- includes="${javac.includes}"
- excludes="${javac.excludes}"
- failonerror="${javac.fail.onerror}">
-
- <src path="${source.java}"/>
- <exclude name="org/jboss/tm/recovery/test/**"/>
- <classpath refid="javac.classpath"/>
- </javac>
- </target>
-
- <!-- Compile etc files (manifests and such) -->
- <target name="compile-etc" depends="init">
- <mkdir dir="${build.etc}"/>
- <copy todir="${build.etc}" filtering="yes">
- <fileset dir="${source.etc}">
- <include name="**/*"/>
- </fileset>
- </copy>
- </target>
-
-
- <!-- ================================================================== -->
- <!-- Archives -->
- <!-- ================================================================== -->
-
- <!--
- | Build all jar files.
- -->
- <target name="jars"
- description="Builds all jar files."
- depends="_buildmagic:build-bypass-check"
- unless="build-bypass.on">
-
- <call target="compile"/>
-
- <mkdir dir="${build.lib}"/>
-
- <!-- Build ${module.name}.jar -->
- <jar jarfile="${build.lib}/${module.name}.jar" manifest="${build.etc}/default.mf">
- <fileset dir="${build.classes}">
- <include name="org/jboss/tm/**"/>
- </fileset>
- </jar>
-
- <!-- Build ${module.name}-client.jar -->
- <jar jarfile="${build.lib}/${module.name}-client.jar" manifest="${build.etc}/default.mf">
- <fileset dir="${build.classes}">
- <include name="**/*Exception.class"/>
- <include name="**/*Error.class"/>
- <include name="**/*MBean.class"/>
-
- <!--
- | jason: not really sure what is meant for the client...
- | someone should trim this list.
- -->
- <include name="org/jboss/tm/**"/>
- </fileset>
- </jar>
-
- <!--
- | JBoss/Testsuite Support
- -->
-
- <!-- testsuite-support.jar -->
- <jar jarfile="${build.lib}/testsuite-support.jar" manifest="${build.etc}/default.mf">
- <fileset dir="${build.classes}">
- <include name="org/jboss/tm/**"/>
- </fileset>
- </jar>
-
- <!-- Update the build marker to allow bypassing -->
- <touch file="${build-bypass.marker}"/>
-
- </target>
-
- <!-- ================================================================== -->
- <!-- Install & Release -->
- <!-- ================================================================== -->
-
- <target name="install"
- description="Install the structure for a release."
- depends="all, _buildmagic:install:default"/>
-
- <target name="release" depends="install"/>
-
- <target name="release-zip"
- description="Builds a ZIP distribution."
- depends="release, _buildmagic:release:zip"/>
-
- <target name="release-tar"
- description="Builds a TAR distribution."
- depends="release, _buildmagic:release:tar"/>
-
- <target name="release-tgz"
- description="Builds a TAR-GZ distribution."
- depends="release, _buildmagic:release:tgz"/>
-
- <target name="release-all"
- description="Builds a distribution for each archive type."
- depends="release-zip, release-tgz"/>
-
-
- <!-- ================================================================== -->
- <!-- Cleaning -->
- <!-- ================================================================== -->
-
- <!-- Clean up all build output -->
- <target name="clean"
- description="Cleans up most generated files."
- depends="_buildmagic:clean">
- </target>
-
- <!-- Clean up all generated files -->
- <target name="clobber"
- description="Cleans up all generated files."
- depends="_buildmagic:clobber, clean">
- </target>
-
-
- <!-- ================================================================== -->
- <!-- Misc. -->
- <!-- ================================================================== -->
-
- <target name="main"
- description="Executes the default target (most)."
- depends="most"/>
-
- <target name="all"
- description="Builds everything."
- depends="jars, docs"/>
-
- <target name="most"
- description="Builds almost everything."
- depends="jars"/>
-
- <target name="help"
- description="Show this help message."
- depends="_buildmagic:help:standard"/>
-
-</project>
Deleted: trunk/transaction/component-info.xml
===================================================================
--- trunk/transaction/component-info.xml 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/component-info.xml 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,26 +0,0 @@
-<project name="transaction-component-info">
- <!-- ============================================================ -->
- <!-- Transaction -->
- <!-- ============================================================ -->
-
- <component id="transaction"
- module="jboss-transaction"
- version="5.0-SNAPSHOT"
- specTitle="JBoss"
- specVersion="5.0.0"
- specVendor="JBoss (http://www.jboss.org)"
- implTitle="JBoss"
- implURL="http://www.jboss.org"
- implVersion="5.0.0"
- implVendor="JBoss.org"
- >
- <artifact id="jboss-transaction.jar"/>
- <artifact id="jboss-transaction-client.jar"/>
- <artifact id="transaction-testsuite-support.jar"/>
- <export>
- <include input="jboss-transaction.jar"/>
- </export>
- </component>
-
-
-</project>
Deleted: trunk/transaction/jbossbuild.xml
===================================================================
--- trunk/transaction/jbossbuild.xml 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/jbossbuild.xml 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,80 +0,0 @@
-<?xml version="1.0"?>
-
-<!--
- JBoss, the OpenSource J2EE webOS
-
- Distributable under LGPL license.
- See terms of license at gnu.org.
--->
-
-<!-- ================================================================== -->
-<!-- Transaction component definition -->
-<!-- ================================================================== -->
-
-<project name="project"
- default="build"
- basedir="."
->
- <import file="../tools/etc/jbossbuild/tasks.xml"/>
- <import file="component-info.xml"/>
-
- <!-- =============================================================== -->
- <!-- The component definition -->
- <!-- =============================================================== -->
-
- <componentdef component="transaction" description="JBoss Transaction">
-
- <!-- ============================================================ -->
- <!-- The main source -->
- <!-- ============================================================ -->
-
- <source id="main"
- excludes="org/jboss/tm/recovery/test/**">
-
- <include component="oswego-concurrent"/>
- <include component="apache-log4j"/>
-
- <include component="common"/>
- <include component="j2se"/>
- <include component="j2ee"/>
- <include component="jmx"/>
- <include component="system"/>
- <include component="jboss/remoting"/>
- </source>
-
- <!-- ============================================================ -->
- <!-- jboss-transaction.jar -->
- <!-- ============================================================ -->
-
- <artifactdef artifact="jboss-transaction.jar">
- <include input="main">
- <include pattern="org/jboss/tm/**"/>
- </include>
- </artifactdef>
-
- <!-- ============================================================ -->
- <!-- jboss-transaction-client.jar -->
- <!-- ============================================================ -->
-
- <artifactdef artifact="jboss-transaction-client.jar">
- <include input="main">
- <include pattern="org/jboss/tm/**"/>
- </include>
- </artifactdef>
-
- <!-- ============================================================ -->
- <!-- transaction-testsuite-support.jar -->
- <!-- ============================================================ -->
-
- <artifactdef artifact="transaction-testsuite-support.jar">
- <include input="main">
- <include pattern="org/jboss/tm/**"/>
- </include>
- </artifactdef>
-
- </componentdef>
-
- <!-- Generate the targets -->
- <generate generate="transaction"/>
-
-</project>
Deleted: trunk/transaction/pom.xml
===================================================================
--- trunk/transaction/pom.xml 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/pom.xml 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,73 +0,0 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
- <parent>
- <groupId>org.jboss.jbossas</groupId>
- <artifactId>jboss-as-parent</artifactId>
- <version>5.0.0-SNAPSHOT</version>
- <relativePath>../build/pom.xml</relativePath>
- </parent>
- <modelVersion>4.0.0</modelVersion>
- <groupId>org.jboss.jbossas</groupId>
- <artifactId>jboss-as-transaction</artifactId>
- <packaging>jar</packaging>
- <name>JBoss Application Server Transaction</name>
- <url>http://www.jboss.com/products/jbossas</url>
- <description>JBoss Application Server (transaction module)</description>
- <build>
- <sourceDirectory>src/main</sourceDirectory>
- <resources>
- <resource>
- <directory>src/resources</directory>
- </resource>
- </resources>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <configuration>
- <excludes>
- <exclude>org/jboss/tm/recovery/test/*.java</exclude>
- </excludes>
- </configuration>
- </plugin>
-
- </plugins>
- </build>
- <dependencies>
- <!-- Compile (global dependencies) -->
- <dependency>
- <groupId>org.jboss.jbossas</groupId>
- <artifactId>jboss-as-j2se</artifactId>
- </dependency>
- <dependency>
- <groupId>org.jboss.jbossas</groupId>
- <artifactId>jboss-as-system-jmx</artifactId>
- </dependency>
- <dependency>
- <groupId>org.jboss.jbossas</groupId>
- <artifactId>jboss-as-main</artifactId>
- </dependency>
- <dependency>
- <groupId>javax.transaction</groupId>
- <artifactId>jta</artifactId>
- </dependency>
- <dependency>
- <groupId>org.jboss</groupId>
- <artifactId>jboss-common-core</artifactId>
- </dependency>
- <dependency>
- <groupId>jboss</groupId>
- <artifactId>jboss-common-logging-spi</artifactId>
- </dependency>
- <dependency>
- <groupId>org.jboss</groupId>
- <artifactId>jboss-transaction-spi</artifactId>
- </dependency>
- <dependency>
- <groupId>jboss</groupId>
- <artifactId>remoting</artifactId>
- </dependency>
- </dependencies>
-
-</project>
Deleted: trunk/transaction/src/etc/default.mf
===================================================================
--- trunk/transaction/src/etc/default.mf 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/etc/default.mf 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,10 +0,0 @@
-Manifest-Version: 1.0
-Created-By: @java.vm.version@ (@java.vm.vendor@)
-Specification-Title: @specification.title@
-Specification-Version: @specification.version@
-Specification-Vendor: @specification.vendor@
-Implementation-Title: @implementation.title@
-Implementation-URL: @implementation.url@
-Implementation-Version: @implementation.version@
-Implementation-Vendor: @implementation.vendor@
-Implementation-Vendor-Id: @implementation.vendor.id@
Deleted: trunk/transaction/src/main/org/jboss/tm/CoordinatorFactory.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/CoordinatorFactory.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/CoordinatorFactory.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,41 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm;
-
-import org.jboss.tm.remoting.interfaces.Coordinator;
-
-/**
- * Interface of a factory that creates references to DTM or OTS coordinators.
- *
- * @author <a href="mailto:reverbel at ime.usp.br">Francisco Reverbel</a>
- * @version $Revision$
- */
-public interface CoordinatorFactory
-{
- /**
- * Creates a reference to a DTM or OTS coordinator associated with the
- * transaction with a given <code>localId</code>.
- * @param localId the local id of a transaction
- * @return a <code>Coordinator</code> reference.
- */
- Coordinator createCoordinator(long localId);
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/GlobalId.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/GlobalId.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/GlobalId.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,226 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm;
-
-import java.io.IOException;
-import javax.transaction.xa.Xid;
-
-/**
- * This object encapsulates the global transaction ID of a transaction.
- * It is similar to an Xid, but holds only the GlobalId part.
- * This implementation is immutable and always serializable at runtime.
- *
- * @see XidImpl
- * @author <a href="mailto:osh at sparre.dk">Ole Husgaard</a>
- * @author <a href="mailto:reverbel at ime.usp.br">Francisco Reverbel</a>
- * @version $Revision$
- */
-public class GlobalId
- implements java.io.Externalizable
-{
- static final long serialVersionUID = -230282197045463046L;
-
- private static String thisClassName;
-
- static {
- thisClassName = GlobalId.class.getName();
- thisClassName =
- thisClassName.substring(thisClassName.lastIndexOf('.') + 1);
- }
-
- /**
- * Format id of this instance.
- */
- private int formatId;
-
- /**
- * Global transaction id of this instance.
- * The coding of this class depends on the fact that this variable is
- * initialized in the constructor and never modified. References to
- * this array are never given away, instead a clone is delivered.
- */
- private byte[] globalId;
-
- /**
- * Hash code of this instance. For a native GlobalId (one whose formatId
- * is XidImpl.JBOSS_FORMAT_ID), this is really a sequence number.
- */
- private int hash;
-
- // Constructors --------------------------------------------------
-
- public GlobalId()
- {
- // Used for Externalizable support
- }
-
- /**
- * Create a new instance. This constructor is package-private, as it
- * trusts the hash parameter to be good.
- */
- GlobalId(int formatId, byte[] globalId, int hash)
- {
- this.formatId = formatId;
- this.globalId = globalId;
- this.hash = hash;
- }
-
- /**
- * Create a new instance. This constructor is public <em>only</em>
- * to get around a class loader problem; it should be package-private.
- */
- public GlobalId(int formatId, byte[] globalId)
- {
- this.formatId = formatId;
- this.globalId = globalId;
- hash = computeHash();
- }
-
- public GlobalId(Xid xid)
- {
- formatId = xid.getFormatId();
- globalId = xid.getGlobalTransactionId();
- if (xid instanceof XidImpl && formatId == XidImpl.JBOSS_FORMAT_ID)
- {
- // native GlobalId: use its hash code (a sequence number)
- hash = xid.hashCode();
- }
- else
- {
- // foreign GlobalId: do the hash computation
- hash = computeHash();
- }
- }
-
- public GlobalId(int formatId, int bqual_length, byte[] tid)
- {
- this.formatId = formatId;
- if (bqual_length == 0)
- globalId = tid;
- else
- {
- int len = tid.length - bqual_length;
- globalId = new byte[len];
- System.arraycopy(tid, 0, globalId, 0, len);
- }
- hash = computeHash();
- }
-
- // Public --------------------------------------------------------
-
- /**
- * Returns the global transaction id of this transaction.
- */
- public byte[] getGlobalTransactionId()
- {
- return (byte[])globalId.clone();
- }
-
- /**
- * Returns the format identifier of this transaction.
- */
- public int getFormatId()
- {
- return formatId;
- }
-
- /**
- * Compare for equality.
- *
- * Instances are considered equal if they both refer to the same
- * global transaction id.
- */
- public boolean equals(Object obj)
- {
- if (obj instanceof GlobalId) {
- GlobalId other = (GlobalId)obj;
-
- if (formatId != other.formatId)
- return false;
-
- if (globalId == other.globalId)
- return true;
-
- if (globalId.length != other.globalId.length)
- return false;
-
- int len = globalId.length;
- for (int i = 0; i < len; ++i)
- if (globalId[i] != other.globalId[i])
- return false;
-
- return true;
- }
- return false;
- }
-
- public int hashCode()
- {
- return hash;
- }
-
- public String toString()
- {
- return thisClassName + "[formatId=" + formatId
- + ", globalId=" + new String(globalId).trim()
- + ", hash=" + hash + "]";
- }
-
- // Externalizable implementation ---------------------------------
-
- public void writeExternal(java.io.ObjectOutput out)
- throws IOException
- {
- out.writeInt(formatId);
- out.writeObject(globalId);
- }
-
- public void readExternal(java.io.ObjectInput in)
- throws IOException, ClassNotFoundException
- {
- formatId = in.readInt();
- globalId = (byte[])in.readObject();
- hash = computeHash();
- }
-
- // Private -------------------------------------------------------
-
- private int computeHash()
- {
- if (formatId == XidImpl.JBOSS_FORMAT_ID)
- {
- return (int)TransactionImpl.xidFactory.extractLocalIdFrom(globalId);
- }
- else
- {
- int len = globalId.length;
- int hashval = 0;
-
- // TODO: use a better hash function
- for (int i = 0; i < len; ++i)
- hashval = 3 * globalId[i] + hashval;
- hashval += formatId;
- return hashval;
- }
- }
-
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/JBossRollbackException.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/JBossRollbackException.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/JBossRollbackException.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,129 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm;
-
-import java.io.PrintStream;
-import java.io.PrintWriter;
-import javax.transaction.RollbackException;
-import org.jboss.util.NestedThrowable;
-
-/**
- * JBossRollbackException.java
- *
- *
- * Created: Sun Feb 9 22:45:03 2003
- *
- * @author <a href="mailto:d_jencks at users.sourceforge.net">David Jencks</a>
- * @version
- */
-
-public class JBossRollbackException
- extends RollbackException
- implements NestedThrowable
-{
- static final long serialVersionUID = 2924502280803535350L;
-
- Throwable t;
-
- public JBossRollbackException()
- {
- super();
- }
-
- public JBossRollbackException(final String message)
- {
- super(message);
- }
-
- public JBossRollbackException(final Throwable t)
- {
- super();
- this.t = t;
- }
-
- public JBossRollbackException(final String message, final Throwable t)
- {
- super(message);
- this.t = t;
- }
-
- // Implementation of org.jboss.util.NestedThrowable
-
- public Throwable getNested()
- {
- return t;
- }
-
- public Throwable getCause()
- {
- return t;
- }
-
- /**
- * Returns the composite throwable message.
- *
- * @return The composite throwable message.
- */
- public String getMessage() {
- return NestedThrowable.Util.getMessage(super.getMessage(), t);
- }
-
- /**
- * Prints the composite message and the embedded stack trace to the
- * specified print stream.
- *
- * @param stream Stream to print to.
- */
- public void printStackTrace(final PrintStream stream)
- {
- if (t == null || NestedThrowable.PARENT_TRACE_ENABLED)
- {
- super.printStackTrace(stream);
- }
- NestedThrowable.Util.print(t, stream);
- }
-
- /**
- * Prints the composite message and the embedded stack trace to the
- * specified print writer.
- *
- * @param writer Writer to print to.
- */
- public void printStackTrace(final PrintWriter writer)
- {
- if (t == null || NestedThrowable.PARENT_TRACE_ENABLED)
- {
- super.printStackTrace(writer);
- }
- NestedThrowable.Util.print(t, writer);
- }
-
- /**
- * Prints the composite message and the embedded stack trace to
- * <tt>System.err</tt>.
- */
- public void printStackTrace()
- {
- printStackTrace(System.err);
- }
-
-}// JBossRollbackException
Deleted: trunk/transaction/src/main/org/jboss/tm/JBossXAException.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/JBossXAException.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/JBossXAException.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,177 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm;
-
-import java.io.PrintWriter;
-import java.io.PrintStream;
-import javax.transaction.xa.XAException;
-
-import org.jboss.util.NestedThrowable;
-
-/**
- * Thrown to indicate a problem with a xaresource related operation.
- *
- * <p>
- * Properly displays linked exception (ie. nested exception)
- * when printing the stack trace.
- *
- * @version <tt>$Revision$</tt>
- * @author <a href="mailto:adrian at jboss.com">Adrian Brock</a>
- */
-public class JBossXAException
- extends XAException
- implements NestedThrowable
-{
- /** The servial version uid*/
- private static final long serialVersionUID = 6614203184612359692L;
-
- /** The linked exception */
- Throwable linked;
-
- /**
- * Rethrow as an xa exception if it is not already
- *
- * @param message the message
- * @param t the original exception
- * @throws XAException the xa exception
- */
- public static void rethrowAsXAException(String message, Throwable t) throws XAException
- {
- if (t instanceof XAException)
- throw (XAException) t;
- else
- throw new JBossXAException(message, t);
- }
-
- /**
- * Construct a <tt>JBossXAException</tt> with the specified detail
- * message.
- *
- * @param msg Detail message.
- */
- public JBossXAException(final String msg)
- {
- super(msg);
- }
-
- /**
- * Construct a <tt>JBossXAException</tt> with the specified detail
- * message and error code.
- *
- * @param code Error code.
- */
- public JBossXAException(final int code)
- {
- super(code);
- }
-
- /**
- * Construct a <tt>JBossXAException</tt> with the specified detail
- * message and linked <tt>Exception</tt>.
- *
- * @param msg Detail message.
- * @param linked Linked <tt>Exception</tt>.
- */
- public JBossXAException(final String msg, final Throwable linked)
- {
- super(msg);
- this.linked = linked;
- }
-
- /**
- * Construct a <tt>JBossXAException</tt> with the specified
- * linked <tt>Exception</tt>.
- *
- * @param linked Linked <tt>Exception</tt>.
- */
- public JBossXAException(final Throwable linked)
- {
- this(linked.getMessage(), linked);
- }
-
- /**
- * Return the nested <tt>Throwable</tt>.
- *
- * @return Nested <tt>Throwable</tt>.
- */
- public Throwable getNested()
- {
- return linked;
- }
-
- /**
- * Return the nested <tt>Throwable</tt>.
- *
- * <p>For JDK 1.4 compatibility.
- *
- * @return Nested <tt>Throwable</tt>.
- */
- public Throwable getCause()
- {
- return linked;
- }
-
- /**
- * Returns the composite throwable message.
- *
- * @return The composite throwable message.
- */
- public String getMessage()
- {
- return NestedThrowable.Util.getMessage(super.getMessage(), linked);
- }
-
- /**
- * Prints the composite message and the embedded stack trace to the
- * specified print stream.
- *
- * @param stream Stream to print to.
- */
- public void printStackTrace(final PrintStream stream)
- {
- if (linked == null || NestedThrowable.PARENT_TRACE_ENABLED)
- super.printStackTrace(stream);
- NestedThrowable.Util.print(linked, stream);
- }
-
- /**
- * Prints the composite message and the embedded stack trace to the
- * specified print writer.
- *
- * @param writer Writer to print to.
- */
- public void printStackTrace(final PrintWriter writer)
- {
- if (linked == null || NestedThrowable.PARENT_TRACE_ENABLED)
- super.printStackTrace(writer);
- NestedThrowable.Util.print(linked, writer);
- }
-
- /**
- * Prints the composite message and the embedded stack trace to
- * <tt>System.err</tt>.
- */
- public void printStackTrace()
- {
- printStackTrace(System.err);
- }
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/LocalId.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/LocalId.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/LocalId.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,211 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm;
-
-/**
- * LocalId is a wrapper for a long value that identifies a transaction within
- * a JBoss server. This implementation is immutable and serializable at
- * runtime.
- *
- * @author <a href="reverbel at ime.usp.br">Francisco Reverbel</a>
- * @version $Revision$
- */
-public class LocalId
- implements java.io.Externalizable
-{
- static final long serialVersionUID = 2076780468014328911L;
-
- /**
- * Long value that identifies a transaction within a JBoss server.
- * This is really a sequence number generated by the XidFactory.
- */
- private long value;
-
-
- // Static --------------------------------------------------------
-
- /** Number of bits in the "transaction generation" part of the local id */
- private static final int TX_GEN_SIZE = 20;
-
- /** Number of bits in a long */
- private static final int LONG_SIZE = 64;
-
- /** Number of bits in the "transaction number" part of the local id */
- private static final int TX_NUM_SIZE = LONG_SIZE - TX_GEN_SIZE;
-
- /** Mask to extract a transaction generation from the lower part of a long */
- private static final long TX_GEN_MASK = (1L << TX_GEN_SIZE) - 1;
-
- /** Mask to extract the transaction number from a local id */
- private static final long TX_NUM_MASK = (1L << TX_NUM_SIZE) - 1;
-
- /**
- * Assemble a local id as a long value with a generation number in its high
- * part (the <code>TX_GEN_SIZE</code> most significant bits) and a
- * transaction number in its low part (the <code>TX_NUM_SIZE</code> least
- * significant bits).
- *
- * @param genNumber the generation number
- * @param txNumber the transaction number.
- * @return a local transaction id.
- */
- public static long assemble(int genNumber, long txNumber)
- {
- return (((long) genNumber) << TX_NUM_SIZE) | (txNumber & TX_NUM_MASK);
- }
-
- /**
- * Extracts the generation number from a local id value.
- *
- * @param localIdValue a local id value.
- * @return the generation number in the <code>TX_GEN_SIZE</code> most
- * significant bits of the local id.
- */
- public static int toGenerationNumber(long localIdValue)
- {
- return (int)((localIdValue >> TX_NUM_SIZE) & TX_GEN_MASK);
- }
-
- /**
- * Extracts a transaction number from a local id value.
- *
- * @param localIdValue a local id value.
- * @return the transaction number in the <code>TX_NUM_SIZE</code> least
- * significant bits of the local id.
- */
- public static long toTransactionNumber(long localIdValue)
- {
- return localIdValue & TX_NUM_MASK;
- }
-
- /**
- * Converts a local id value into a string.
- *
- * @param l a local id value
- * @return a string of the form "<em>gn</em>:<em>tn</em>", where
- * <em>gn</em> is the generation number and <em>tn</em> is
- * the transaction number.
- */
- public static String toString(long l)
- {
- return "" + toGenerationNumber(l) + ":" + toTransactionNumber(l);
- }
-
- /**
- * Copies a local id value into a byte array.
- *
- * @param localIdValue a local id value
- * @param dst the destination byte array
- * @param dstBegin the index of the first element of <code>dst</code> that
- * will receive a byte of the local id.
- */
- public static void toByteArray(long localIdValue, byte[] dst, int dstBegin)
- {
- dst[dstBegin + 0] = (byte)(0xff & (localIdValue >>> 56));
- dst[dstBegin + 1] = (byte)(0xff & (localIdValue >>> 48));
- dst[dstBegin + 2] = (byte)(0xff & (localIdValue >>> 40));
- dst[dstBegin + 3] = (byte)(0xff & (localIdValue >>> 32));
- dst[dstBegin + 4] = (byte)(0xff & (localIdValue >>> 24));
- dst[dstBegin + 5] = (byte)(0xff & (localIdValue >>> 16));
- dst[dstBegin + 6] = (byte)(0xff & (localIdValue >>> 8));
- dst[dstBegin + 7] = (byte)(0xff & (localIdValue >>> 0));
- }
-
- /**
- * Gets a local id value from a byte array/
- *
- * @param src the source byte array
- * @param srcBegin the index of the first element of <code>src</code> that
- * contains a byte of the local id.
- * @return a local id extracted from the byte array.
- */
- public static long fromByteArray(byte[] src, int srcBegin)
- {
- return ((long)(src[srcBegin + 0] & 0xff) << 56)
- | ((long)(src[srcBegin + 1] & 0xff) << 48)
- | ((long)(src[srcBegin + 2] & 0xff) << 40)
- | ((long)(src[srcBegin + 3] & 0xff) << 32)
- | ((long)(src[srcBegin + 4] & 0xff) << 24)
- | ((long)(src[srcBegin + 5] & 0xff) << 16)
- | ((long)(src[srcBegin + 6] & 0xff) << 8)
- | ((long)(src[srcBegin + 7] & 0xff));
- }
-
- // Constructors --------------------------------------------------
-
- /**
- * No-arg constructor for Externalizable support.
- */
- public LocalId()
- {
- }
-
- /**
- * Create a new instance. This constructor is public <em>only</em>
- * to get around a class loader problem; it should be package-private.
- */
- public LocalId(long value)
- {
- this.value = value;
- }
-
- public LocalId(XidImpl xid)
- {
- this(xid.getLocalIdValue());
- }
-
- // Public --------------------------------------------------------
-
- public long getValue()
- {
- return value;
- }
-
- /**
- * Compare for equality.
- */
- public boolean equals(Object obj)
- {
- return (obj instanceof LocalId) ? (value == ((LocalId)obj).value)
- : false;
- }
-
- public int hashCode()
- {
- return (int)value;
- }
-
- // Externalizable implementation ---------------------------------
- public void writeExternal(java.io.ObjectOutput out)
- throws java.io.IOException
- {
- out.writeLong(value);
- }
-
- public void readExternal(java.io.ObjectInput in)
- throws java.io.IOException, ClassNotFoundException
- {
- value = in.readLong();
- }
-
-}
-
Deleted: trunk/transaction/src/main/org/jboss/tm/OTSContextFactory.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/OTSContextFactory.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/OTSContextFactory.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,84 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm;
-
-import org.jboss.tm.remoting.interfaces.Coordinator;
-
-/**
- * Interface of a factory that creates OTS propagation contexts.
- *
- * @author <a href="mailto:reverbel at ime.usp.br">Francisco Reverbel</a>
- * @version $Revision$
- */
-public interface OTSContextFactory
-{
- /**
- * Creates an OTS context with the specified <code>formatId</code>,
- * <code>globalId</code>, and <code>coordinator</code>. The OTS context
- * will contain a null <code>Terminator</code> reference and an
- * <code>org.omg.CosTransactions.Coordinator</code> reference extracted from
- * the <code>coordinator</code> parameter, which must be an instance of
- * <code>org.jboss.tm.iiop.wrapper.OTSCoordinatorWrapper</code>.
- * It will contain zero in its timeout field. The caller should use the
- * method <code>setTimeout</code> to set the timeout field of the newly
- * created OTS context.
- *
- * @param formatId the format id to be stored in the OTS context
- * @param globalId the global id to be stored in the OTS context
- * @param coordinator an <code>org.jboss.tm.iiop.wrapper.OTSCoordinatorWrapper</code>
- * containing the <code>org.omg.CosTransactions.Coordinator</code>
- * reference to be stored in the OTS context
- * @return an instance of <code>org.omg.CosTransactions.PropagationContext</code>.
- */
- Object createOTSContext(int formatId,
- byte[] globalId,
- Coordinator coordinator);
-
- /**
- * Creates an OTS context with the specified <code>formatId</code> and
- * <code>globalId</code>, and with an
- * <code>org.omg.CosTransactions.Coordinator</code> reference that
- * corresponds to the local transaction whose local id is
- * <code>coordinatorLocalId</code>. The OTS context will contain a null
- * <code>Terminator</code> reference and zero in its timeout field.
- * The caller should use the method <code>setTimeout</code> to set the
- * timeout field of the newly created OTS context.
- *
- * @param formatId the format id to be stored in the OTS context
- * @param globalId the global id to be stored in the OTS context
- * @param coordinatorLocalId the local id of the transaction associated with
- * the coordinator reference to be stored in the OTS context
- * @return an instance of <code>org.omg.CosTransactions.PropagationContext</code>.
- */
- Object createOTSContext(int formatId,
- byte[] globalId,
- long coordinatorLocalId);
-
- /**
- * Sets the timeout field of the specified OTS context.
- * @param otsContext an instance of <code>org.omg.CosTransactions.PropagationContext</code>
- * @param timeout the timeout value, in seconds, to be stored in the OTS
- * context.
- */
- void setTimeout(Object otsContext, int timeout);
-
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/ResourceFactory.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/ResourceFactory.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/ResourceFactory.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,46 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm;
-
-import org.jboss.tm.remoting.interfaces.Resource;
-
-/**
- * Interface of a factory that creates references to DTM or OTS resources.
- * In order to register itself as a subcoordinator with the parent coordinator,
- * a <code>TransactionImpl</code> instance needs to obtain a reference to a
- * resource associated with itself. It calls a <code>ResourceFactory</code> to
- * obtain that reference, which it then uses as the resource parameter in a
- * call to <code>registerResource</code> on the parent coordinator.
- *
- * @author <a href="mailto:reverbel at ime.usp.br">Francisco Reverbel</a>
- * @version $Revision$
- */
-public interface ResourceFactory
-{
- /**
- * Creates a reference to a DTM or OTS resource that corresponds to the
- * transaction with a given <code>localId</code>.
- * @param localId the local id of a transaction
- * @return a <code>Resource</code> reference
- */
- Resource createResource(long localId);
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/StringRemoteRefConverter.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/StringRemoteRefConverter.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/StringRemoteRefConverter.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,74 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm;
-
-import org.jboss.tm.remoting.interfaces.RecoveryCoordinator;
-import org.jboss.tm.remoting.interfaces.Resource;
-
-/**
- * Converts stringfied references to remote <code>Resource</code>s and
- * <code>RecoveryCoordinator</code>s back to remote references. This
- * interface serves the purpose of avoiding a dependency from the transaction
- * recovery module to the CORBA/OTS module.
- *
- * @author <a href="mailto:reverbel at ime.usp.br">Francisco Reverbel</a>
- * @version $Revision$
- */
-public interface StringRemoteRefConverter
-{
- /**
- * Converts a stringfied reference to a remote <code>Resource</code>
- * back to a remote reference.
- *
- * @param strResource a stringfied reference to a remote
- * <code>Resource</code>
- * @return a remote reference to the <code>Resource</code>.
- */
- Resource stringToResource(String strResource);
-
- /**
- * Converts a stringfied reference to a remote
- * <code>RecoveryCoordinator</code> back to a remote reference.
- *
- * @param strRecCoordinator a stringfied reference to a remote
- * <code>RecoveryCoordinator</code>
- * @return a remote reference to the <code>RecoveryCoordinator</code>
- */
- RecoveryCoordinator stringToRecoveryCoordinator(String strRecCoordinator);
-
- /**
- * Takes a remote reference to a resource and converts it to a string.
- *
- * @param res a remote reference to a resource
- * @return a string that represents the remote resource.
- */
- String resourceToString(Resource res);
-
- /**
- * Takes a remote reference to recovery coordinator and converts it to a
- * string.
- *
- * @param recoveryCoord a remote reference to a recovery coordinator
- * @return a string that represents the remote recovery coordinator.
- */
- String recoveryCoordinatorToString(RecoveryCoordinator recoveryCoord);
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/TMUtil.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/TMUtil.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/TMUtil.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,94 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm;
-
-import javax.naming.Context;
-import javax.naming.InitialContext;
-import javax.naming.NamingException;
-import javax.transaction.Transaction;
-import javax.transaction.TransactionManager;
-
-import org.jboss.logging.Logger;
-
-/**
- * Transaction Manager utility methods.
- *
- * @author <a href="mailto:reverbel at ime.usp.br">Francisco Reverbel</a>
- * @version $Revision$
- */
-public class TMUtil
-{
-
- private static final Logger log =
- Logger.getLogger(TMUtil.class);
-
- private static TransactionManager tm;
-
- // enforce non-instantiability
- private TMUtil()
- {
- }
-
- /**
- * Gets a <code>Transaction</code> instance given its <code>LocalId</code>.
- */
- public static Transaction getTransaction(LocalId localId)
- {
- TransactionPropagationContextImporter tpcImporter =
- TransactionPropagationContextUtil.getTPCImporter();
-
- return tpcImporter.importTransactionPropagationContext(localId);
- }
-
- /**
- * Gets a reference to the transaction manager.
- */
- public static TransactionManager getTransactionManager()
- {
- if (tm == null)
- {
- try
- {
- Context ctx = new InitialContext();
- tm = (TransactionManager)ctx.lookup("java:/TransactionManager");
- }
- catch (NamingException ex)
- {
- log.error("java:/TransactionManager lookup failed", ex);
- }
- }
- return tm;
- }
-
- /**
- * Time-out conversion from milliseconds to seconds.
- */
- public static int divideAndRoundUp(long m, long n)
- {
- long retval = m / n;
-
- if ((m % n) != 0)
- retval = retval + 1;
- return (int)retval ;
- }
-
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/TransactionImpl.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/TransactionImpl.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/TransactionImpl.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,5402 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm;
-
-import java.lang.reflect.Proxy;
-import java.rmi.NoSuchObjectException;
-import java.rmi.RemoteException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.resource.spi.work.Work;
-import javax.resource.spi.work.WorkCompletedException;
-import javax.resource.spi.work.WorkException;
-import javax.transaction.HeuristicCommitException;
-import javax.transaction.HeuristicMixedException;
-import javax.transaction.HeuristicRollbackException;
-import javax.transaction.RollbackException;
-import javax.transaction.Status;
-import javax.transaction.Synchronization;
-import javax.transaction.SystemException;
-import javax.transaction.Transaction;
-import javax.transaction.TransactionRolledbackException;
-import javax.transaction.xa.XAException;
-import javax.transaction.xa.XAResource;
-import javax.transaction.xa.Xid;
-
-import org.jboss.logging.Logger;
-import org.jboss.tm.integrity.TransactionIntegrity;
-import org.jboss.tm.recovery.HeuristicStatus;
-import org.jboss.tm.recovery.LogRecord;
-import org.jboss.tm.recovery.RecoveryLogger;
-import org.jboss.tm.recovery.RecoveryTestingException;
-import org.jboss.tm.recovery.TxCompletionHandler;
-import org.jboss.tm.recovery.XAResourceAccess;
-import org.jboss.tm.recovery.XAWork;
-import org.jboss.tm.remoting.interfaces.Coordinator;
-import org.jboss.tm.remoting.interfaces.HeuristicHazardException;
-import org.jboss.tm.remoting.interfaces.RecoveryCoordinator;
-import org.jboss.tm.remoting.interfaces.Resource;
-import org.jboss.tm.remoting.interfaces.TransactionAlreadyPreparedException;
-import org.jboss.tm.remoting.interfaces.TransactionInactiveException;
-import org.jboss.tm.remoting.interfaces.TransactionNotPreparedException;
-import org.jboss.tm.remoting.interfaces.TxPropagationContext;
-import org.jboss.tm.remoting.interfaces.Vote;
-import org.jboss.util.timeout.Timeout;
-import org.jboss.util.timeout.TimeoutFactory;
-import org.jboss.util.timeout.TimeoutTarget;
-
-/**
- * Our <code>Transaction</code> implementation.
- *
- * @author <a href="mailto:rickard.oberg at telkel.com">Rickard Oberg</a>
- * @author <a href="mailto:marc.fleury at telkel.com">Marc Fleury</a>
- * @author <a href="mailto:osh at sparre.dk">Ole Husgaard</a>
- * @author <a href="mailto:toby.allsopp at peace.com">Toby Allsopp</a>
- * @author <a href="mailto:jason at planet57.com">Jason Dillon</a>
- * @author <a href="mailto:d_jencks at users.sourceforge.net">David Jencks</a>
- * @author <a href="mailto:bill at jboss.org">Bill Burke</a>
- * @author <a href="mailto:adrian at jboss.com">Adrian Brock</a>
- * @author <a href="mailto:reverbel at ime.usp.br">Francisco Reverbel</a>
- * @author <a href="mailto:dimitris at jboss.org">Dimitris Andreadis</a>
- * @version $Revision$
- * @see TxManager
- */
-public class TransactionImpl
- implements Transaction, TimeoutTarget
-{
- // Constants -----------------------------------------------------
-
- /**
- * Code meaning "no heuristics seen",
- * must not be XAException.XA_HEURxxx
- */
- private static final int HEUR_NONE = 0;
-
- /**
- * Code meaning "heuristics seen, but no additional info is available",
- * must not be XAException.XA_HEURxxx
- */
- private static final int HEUR_UNKNOWN = XAException.XA_RETRY;
-
- // Resource states
- private final static int RS_NEW = 0; // not yet enlisted
- private final static int RS_ENLISTED = 1; // enlisted
- private final static int RS_SUSPENDED = 2; // suspended
- private final static int RS_ENDED = 3; // not associated
- private final static int RS_VOTE_READONLY = 4; // voted read-only
- private final static int RS_VOTE_OK = 5; // voted ok
- private final static int RS_FORGOT = 6; // RM has forgotten
- private final static int RS_COMMITTED = 7; // committed
- private final static int RS_ROLLEDBACK = 8; // rolledback
- private final static int RS_HEUR_OUTCOME = 8; // had an heuristic outcome
- private final static int RS_ERROR = 9; // error condition (no use retrying)
-
- // Attributes ----------------------------------------------------
-
- /**
- * True if trace messages should be logged.
- */
- private boolean trace = log.isTraceEnabled();
-
- /**
- * The ID of this transaction.
- */
- private XidImpl xid;
-
- private HashSet threads = new HashSet(1);
-
- private Map transactionLocalMap = Collections.synchronizedMap(new HashMap());
-
- private Throwable cause;
-
- /**
- * True for a foreign transaction that has been imported either through an
- * DTM/OTS transaction propagation context or via JCA transaction inflow;
- * false for a locally started transaction.
- */
- private final boolean foreignTx;
-
- /**
- * This transaction's parent coordinator, or null if this transaction does
- * not have a parent coordinator. A transaction with no parent coodinator
- * is either a (locally started) root transaction or a foreign transaction
- * that has been imported via JCA transaction inflow.
- */
- private Coordinator parentCoordinator = null;
-
- /**
- * The resource registered by transaction with the parent coordinator.
- */
- private Resource registeredResource = null;
-
- /**
- * This transaction's recovery coordinator, or null this transaction did not
- * register itself as a remote resource with the parent coordinator.
- */
- private RecoveryCoordinator recoveryCoordinator = null;
-
- /**
- * The inbound branch qualifier, if this is a foreign transaction that has
- * been imported via JCA transaction inflow, or null otherwise.
- */
- private byte[] inboundBranchQualifier = null;
-
- /**
- * The synchronizations to call back.
- */
- private Synchronization[] sync = new Synchronization[3];
-
- /**
- * Size of allocated synchronization array.
- */
- private int syncAllocSize = 3;
-
- /**
- * Count of synchronizations for this transaction.
- */
- private int syncCount = 0;
-
- /**
- * A list of the XAResources that have participated in this transaction.
- */
- private ArrayList xaResources = new ArrayList(3);
-
- /**
- * A list of the remote resources that have participated in this transaction.
- */
- private ArrayList remoteResources = new ArrayList(3);
-
- /**
- * The XAResource used in the last resource gambit
- */
- private EnlistedXAResource lastResource;
-
- /**
- * Flags that it is too late to enlist new resources.
- */
- private boolean resourcesEnded = false;
-
- /**
- * Last branch id used.
- */
- private long lastBranchId = 0;
-
- /**
- * Status of this transaction.
- */
- private int status;
-
- /**
- * The heuristics status of this transaction.
- */
- private int heuristicCode = HEUR_NONE;
-
- /**
- * The time when this transaction was started.
- */
- private long start;
-
- /**
- * The timeout handle for this transaction.
- */
- private Timeout timeout;
-
- /**
- * Timeout in millisecs
- */
- private long timeoutPeriod;
-
- /**
- * Mutex for thread-safety. This should only be changed in the
- * <code>lock()</code> and <code>unlock()</code> methods.
- */
- private Thread locked = null;
-
- /**
- * The lock depth
- */
- private int lockDepth = 0;
-
- /**
- * Any current work associated with the transaction
- */
- private Work work;
-
- /**
- * Flags that we are done with this transaction and that it can be reused.
- */
- private boolean done = false;
-
- /**
- * This transaction's DTM propagation context.
- */
- private TxPropagationContext dtmPropagationContext = null;
-
- /**
- * This transaction's OTS propagation context.
- */
- private Object otsPropagationContext = null;
-
- /**
- * This transaction's TxCompletionHandler.
- */
- private TxCompletionHandler completionHandler = null;
-
- /**
- * Number of XA resources that reported transient problems.
- */
- private int xaResourcesToRetry = 0;
-
- /**
- * Number of remote resources that reported transient problems.
- */
- private int remoteResourcesToRetry = 0;
-
- /**
- * Timeout before calling <code>replayCompletion</code> on the recovery
- * the coordinator when waiting for the coordinator in the prepared state.
- */
- private Timeout preparedTimeout = null;
-
- /**
- * Timeout before retrying commit or rollback calls on XA resources that
- * reported transient problems.
- */
- private Timeout xaRetryTimeout = null;
-
- /**
- * List of <code>EnlistedXAResource</code> instances with heuristic
- * decisions.
- */
- private List xaResourcesWithHeuristicDecisions = null;
-
- /**
- * List of <code>EnlistedRemoteResource</code> instances with heuristic
- * decisions.
- */
- private List remoteResourcesWithHeuristicDecisions = null;
-
- /**
- * Counts how many resources were committed.
- */
- private int committedResources = 0;
-
- /**
- * Counts how many resources were rolled back.
- */
- private int rolledbackResources = 0;
-
- /**
- * True if this <code>TransactionImpl</code> could not reach a resource
- * during the second phase of 2PC.
- */
- private boolean heuristicHazard = false;
-
- // Static --------------------------------------------------------
-
- /**
- * Class logger, we don't want a new logger with every transaction.
- */
- private static Logger log = Logger.getLogger(TransactionImpl.class);
-
- /**
- * Factory for Xid instances of specified class.
- * This is set from the <code>TransactionManagerService</code>
- * MBean.
- */
- static XidFactoryBase xidFactory;
-
- static XAExceptionFormatter xaExceptionFormatter;
-
- /** The timeout factory */
- static TimeoutFactory timeoutFactory = TimeoutFactory.getSingleton();
-
- /**
- * CoordinatorFactory that creates remote references to DTM coordinators,
- * or null if the DTM is not employed.
- */
- private static CoordinatorFactory dtmCoordinatorFactory = null;
-
- /**
- * ResourceFactory that creates remote references to DTM resources,
- * or null if the DTM is not employed.
- */
- private static ResourceFactory dtmResourceFactory = null;
-
- /**
- * ResourceFactory that creates remote references to OTS resources,
- * or null if OTS is not employed.
- */
- private static ResourceFactory otsResourceFactory = null;
-
- /**
- * Factory that creates OTS transaction propagation contexts,
- * or null if OTS is not employed.
- */
- private static OTSContextFactory otsContextFactory = null;
-
- /**
- * True if coordinator interposition is enabled.
- */
- private static boolean interpositionEnabled = false;
-
- /**
- * Object that converts between strings and remote references for
- * DTM objects, or null if DTM is not employed.
- */
- private static StringRemoteRefConverter dtmStrRemoteRefConverter = null;
-
- /**
- * Object that converts between strings and remote references for
- * OTS objects, or null if OTS is not employed.
- */
- private static StringRemoteRefConverter otsStrRemoteRefConverter = null;
-
- /**
- * This static code is only present for testing purposes so a
- * tm can be usable without a lot of setup.
- */
- public static XidFactoryBase defaultXidFactory()
- {
- if (xidFactory == null)
- {
- XidFactoryImpl impl = new XidFactoryImpl();
- impl.start();
- xidFactory = impl;
- }
- return xidFactory;
- }
-
- /**
- * Setter for <code>dtmCoordinatorFactory</code>.
- */
- static void setDTMCoordinatorFactory(CoordinatorFactory dtmCoordinatorFactory)
- {
- TransactionImpl.dtmCoordinatorFactory = dtmCoordinatorFactory;
- }
-
- /**
- * Setter for <code>dtmResourceFactory</code>.
- */
- static void setDTMResourceFactory(ResourceFactory dtmResourceFactory)
- {
- TransactionImpl.dtmResourceFactory = dtmResourceFactory;
- }
-
- /**
- * Setter for <code>otsResourceFactory</code>.
- */
- static void setOTSResourceFactory(ResourceFactory otsResourceFactory)
- {
- TransactionImpl.otsResourceFactory = otsResourceFactory;
- }
-
- /**
- * Setter for <code>otsContextFactory</code>.
- */
- static void setOTSContextFactory(OTSContextFactory otsContextFactory)
- {
- TransactionImpl.otsContextFactory = otsContextFactory;
- }
-
- /**
- * Setter for <code>interpositionEnabled</code>.
- */
- static void setInterpositionEnabled(boolean interpositionEnabled)
- {
- TransactionImpl.interpositionEnabled = interpositionEnabled;
- }
-
- /**
- * Getter for <code>interpositionEnabled</code>.
- */
- static boolean getInterpositionEnabled()
- {
- return TransactionImpl.interpositionEnabled;
- }
-
- /**
- * Setter for <code>dtmStrRemoteRefConverter</code>.
- */
- static void setDTMStrRemoteRefConverter(
- StringRemoteRefConverter dtmStrRemoteRefConverter)
- {
- TransactionImpl.dtmStrRemoteRefConverter = dtmStrRemoteRefConverter;
- }
-
- /**
- * Setter for <code>otsStrRemoteRefConverter</code>.
- */
- static void setOTSStrRemoteRefConverter(
- StringRemoteRefConverter otsStrRemoteRefConverter)
- {
- TransactionImpl.otsStrRemoteRefConverter = otsStrRemoteRefConverter;
- }
-
- /**
- * Converts a stringfied reference to a remote resource back to a remote
- * reference.
- *
- * @param strResource a stringfied reference to a remote resource
- * @return a remote reference to the resource.
- */
- static Resource stringToResource(String strResource)
- {
- if (strResource.startsWith("IOR:"))
- {
- if (otsStrRemoteRefConverter != null)
- return otsStrRemoteRefConverter.stringToResource(strResource);
- else
- throw new IllegalArgumentException();
- }
- else
- {
- if (dtmStrRemoteRefConverter != null)
- return dtmStrRemoteRefConverter.stringToResource(strResource);
- else
- throw new IllegalArgumentException();
- }
- }
-
- /**
- * Converts a stringfied reference to a remote recovery coordinator back
- * to a remote reference.
- *
- * @param strRecCoordinator a stringfied reference to a remote recovery
- * coordinator
- * @return a remote reference to the recovery coordinator.
- */
- static RecoveryCoordinator stringToRecoveryCoordinator(
- String strRecCoordinator)
- {
- if (strRecCoordinator.startsWith("IOR:"))
- {
- if (otsStrRemoteRefConverter != null)
- return otsStrRemoteRefConverter.stringToRecoveryCoordinator(
- strRecCoordinator);
- else
- throw new IllegalArgumentException();
- }
- else
- {
- if (dtmStrRemoteRefConverter != null)
- return dtmStrRemoteRefConverter.stringToRecoveryCoordinator(
- strRecCoordinator);
- else
- throw new IllegalArgumentException();
- }
- }
-
- /**
- * Takes a remote reference to a resource and converts it to a string.
- *
- * @param res a remote reference to a resource
- * @return a string that represents the remote resource.
- */
- static String resourceToString(Resource res)
- {
- if (Proxy.isProxyClass(res.getClass()))
- {
- if (dtmStrRemoteRefConverter != null)
- return dtmStrRemoteRefConverter.resourceToString(res);
- else
- throw new IllegalArgumentException();
- }
- else
- {
- if (otsStrRemoteRefConverter != null)
- return otsStrRemoteRefConverter.resourceToString(res);
- else
- throw new IllegalArgumentException();
- }
- }
-
- /**
- * Takes a remote reference to a recovery coordinator and converts it to a
- * string.
- *
- * @param recoveryCoord a remote reference to a recovery coordinator
- * @return a string that represents the remote recovery coordinator.
- */
- static String recoveryCoordinatorToString(RecoveryCoordinator recoveryCoord)
- {
- if (Proxy.isProxyClass(recoveryCoord.getClass()))
- {
- if (dtmStrRemoteRefConverter != null)
- return dtmStrRemoteRefConverter.recoveryCoordinatorToString(
- recoveryCoord);
- else
- throw new IllegalArgumentException();
- }
- else
- {
- if (otsStrRemoteRefConverter != null)
- return otsStrRemoteRefConverter.recoveryCoordinatorToString(
- recoveryCoord);
- else
- throw new IllegalArgumentException();
- }
- }
-
- // Constructors --------------------------------------------------
-
- /**
- * Constructor for transactions started locally.
- */
- TransactionImpl(long timeout)
- {
- foreignTx = false;
- xid = xidFactory.newXid();
-
- status = Status.STATUS_ACTIVE;
-
- start = System.currentTimeMillis();
- this.timeout = timeoutFactory.createTimeout(start + timeout, this);
- this.timeoutPeriod = timeout;
- if (trace)
- log.trace("Created new instance for tx=" + toString());
- }
-
- /**
- * Constructor for foreign transactions imported through DTM/OTS transaction
- * propagation contexts.
- */
- TransactionImpl(GlobalId gid, Coordinator parentCoordinator, long timeout)
- {
- foreignTx = true;
- xid = xidFactory.newBranch(gid);
-
- this.parentCoordinator = parentCoordinator;
-
- status = Status.STATUS_ACTIVE;
-
- start = System.currentTimeMillis();
- this.timeout = timeoutFactory.createTimeout(start + timeout, this);
- this.timeoutPeriod = timeout;
- if (trace)
- log.trace("Created new instance for tx=" + toString());
- }
-
- /**
- * Constructor for foreign transactions imported through the JCA transaction
- * inflow mechanism.
- */
- TransactionImpl(GlobalId gid, byte[] inboundBranchQualifier, long timeout)
- {
- foreignTx = true;
- xid = xidFactory.newBranch(gid);
-
- this.inboundBranchQualifier = inboundBranchQualifier;
-
- status = Status.STATUS_ACTIVE;
-
- start = System.currentTimeMillis();
- this.timeout = timeoutFactory.createTimeout(start + timeout, this);
- this.timeoutPeriod = timeout;
- if (trace)
- log.trace("Created new instance for tx=" + toString());
-
- }
-
- /**
- * Constructor to recreate a locally-started transaction that does not
- * involve other transaction managers. It is intended to be called at
- * recovery time, for recreating transactions that were in the committing
- * state when the server crashed. Such a transaction completed the first
- * phase of the 2PC protocol and logged the commit decision, but it must
- * still send commit messages to some or all of its <code>XAResource</code>s.
- *
- * @param localId the local id of a locally-started transaction that is in
- * the committing state and does not involve other transaction
- * managers
- * @param preparedXAWorkList a list of <code>org.jboss.tm.XAWork</code>
- * instances containing one element for each
- * <code>XAResource</code> that is enlisted with the transaction
- * and is still in the prepared state
- * @param completionHandler the
- * <code>org.jboss.tm.recovery.TxCompletionHandler</code> to be
- * notifed when the second phase of the 2PC completes
- * @param heurData either null or a <code>LogRecord.HeurData</code> instance
- * contaning information on a locally-detected heuristic hazard.
- */
- TransactionImpl(long localId,
- List preparedXAWorkList,
- TxCompletionHandler completionHandler,
- LogRecord.HeurData heurData)
- {
- foreignTx = false;
- xid = xidFactory.recreateXid(localId);
- status = Status.STATUS_COMMITTING;
- if (heurData != null)
- {
- heuristicCode = heurData.heuristicStatusCode;
- heuristicHazard = heurData.locallyDetectedHeuristicHazard;
- }
- this.completionHandler = completionHandler;
- for (Iterator it = preparedXAWorkList.iterator(); it.hasNext(); )
- {
- XAWork preparedXAWork = (XAWork) it.next();
- EnlistedXAResource r = new EnlistedXAResource(preparedXAWork);
- xaResources.add(r);
-
- }
- commitXAResourcesAfterTimeout();
- }
-
- /**
- * Constructor to recreate a locally-started transaction that involves other
- * transaction managers. Involving other transaction managers means that
- * there are remote <code>Resource</code>s enlisted with the transaction.
- * This constructor is intended to be called at recovery time, for recreating
- * transactions that were in the committing state when the server crashed.
- * Such a transaction completed the first phase of the 2PC protocol and
- * logged the commit decision, but it must still send commit messages to
- * some or all of its resources (<code>XAResource</code>s and remote
- * <code>Resource</code>s).
- *
- * @param localId the local id of a locally-started transaction that is in
- * the committing state and involves other transaction managers
- * @param preparedXAWorkList list of <code>org.jboss.tm.XAWork</code>
- * instances containing one element for each
- * <code>XAResource</code> that is enlisted with the transaction
- * and is still in the prepared state
- * @param resources an array with stringfied references for the remote
- * <code>Resource</code>s enlisted with the transaction
- * @param completionHandler the
- * <code>org.jboss.tm.recovery.TxCompletionHandler</code> to be
- * notifed when the second phase of the 2PC completes
- * @param heurData either null or a <code>LogRecord.HeurData</code> instance
- * contaning information on a locally-detected heuristic hazard.
- */
- TransactionImpl(long localId,
- List preparedXAWorkList,
- String[] resources,
- TxCompletionHandler completionHandler,
- LogRecord.HeurData heurData)
- {
- foreignTx = false;
- xid = xidFactory.recreateXid(localId);
- status = Status.STATUS_COMMITTING;
- this.completionHandler = completionHandler;
- if (heurData != null)
- {
- heuristicCode = heurData.heuristicStatusCode;
- heuristicHazard = heurData.locallyDetectedHeuristicHazard;
- }
- for (Iterator it = preparedXAWorkList.iterator(); it.hasNext(); )
- {
- XAWork preparedXAWork = (XAWork) it.next();
- EnlistedXAResource r = new EnlistedXAResource(preparedXAWork);
- xaResources.add(r);
- }
- for (int i = 0; i < resources.length; i++)
- {
- EnlistedRemoteResource r =
- new EnlistedRemoteResource(stringToResource(resources[i]), true);
- remoteResources.add(r);
- }
- lock();
- try
- {
- retryCommitRemoteResources();
- }
- finally
- {
- unlock();
- }
- if (preparedXAWorkList.size() > 0)
- {
- // Keep this TransactionImpl around to
- // commit its XAResources at a later time.
- commitXAResourcesAfterTimeout();
- }
- else if (remoteResourcesToRetry == 0 && heuristicCode == HEUR_NONE)
- {
- // This TransactionImpl is not needed anymore.
- lock();
- try
- {
- completeTransaction();
- }
- finally
- {
- unlock();
- }
- }
- else
- {
- // Do nothing. Just keep this TransactionImpl around to receive
- // replayCompletion calls from remote resources.
- }
- }
-
- /**
- * Constructor to recreate a foreign transaction that entered this virtual
- * machine in a transaction context propagated along with a remote method
- * invocation. This constructor is intended to be called at recovery time,
- * for recreating transactions that were in the prepared state when the
- * server crashed.
- *
- * @param localId the local id of a foreign transaction that entered this
- * virtual machine in a transaction propagation context and is
- * propagated along with a remote method invocation and is in
- * the prepared state
- * @param inboundFormatId format id part of the foreign transaction
- * identifier that entered this virtual machine
- * @param globalTransactionId global id part of the foreign transaction
- * identifier that entered this virtual machine
- * @param recoveryCoord an stringfied reference to the transaction branch's
- * <code>RecovertyCoordinator</code>
- * @param preparedXAWorkList a list of <code>org.jboss.tm.XAWork</code>
- * instances containing one element for each
- * <code>XAResource</code> enlisted with the transaction
- * @param resources an array with stringfied references for the remote
- * <code>Resource</code>s enlisted with the transaction
- * @param completionHandler the
- * <code>org.jboss.tm.recovery.TxCompletionHandler</code> to be
- * notifed when the second phase of the 2PC completes
- * @param heurData either null or a <code>LogRecord.HeurData</code> instance
- * contaning information on a locally-detected heuristic hazard.
- */
- TransactionImpl(long localId,
- int inboundFormatId,
- byte[] globalTransactionId,
- String recoveryCoord,
- List preparedXAWorkList,
- String[] resources,
- TxCompletionHandler completionHandler,
- LogRecord.HeurData heurData)
- {
- foreignTx = true;
- GlobalId globalId = new GlobalId(inboundFormatId, globalTransactionId);
- xid = xidFactory.recreateXid(localId, globalId);
- recoveryCoordinator = stringToRecoveryCoordinator(recoveryCoord);
- if (heurData == null)
- status = Status.STATUS_PREPARED;
- else
- {
- status = heurData.transactionStatus;
- heuristicCode = heurData.heuristicStatusCode;
- heuristicHazard = heurData.locallyDetectedHeuristicHazard;
- }
- this.completionHandler = completionHandler;
- for (Iterator it = preparedXAWorkList.iterator(); it.hasNext(); )
- {
- XAWork preparedXAWork = (XAWork) it.next();
- EnlistedXAResource r = new EnlistedXAResource(preparedXAWork);
- xaResources.add(r);
- }
- for (int i = 0; i < resources.length; i++)
- {
- EnlistedRemoteResource r =
- new EnlistedRemoteResource(stringToResource(resources[i]), true);
- remoteResources.add(r);
- }
-
- // Set my registeredResource using the appropriate resource factory.
- if (Proxy.isProxyClass(recoveryCoordinator.getClass()))
- {
- // DTM coordinator case
- if (dtmResourceFactory != null)
- registeredResource = dtmResourceFactory.createResource(localId);
- else
- log.warn("Error reconstructing TransactionImpl instance for tx="
- + toString() + " -- DTM resource factory missing." );
- }
- else
- {
- // OTS coordinator case
- if (otsResourceFactory != null)
- registeredResource = otsResourceFactory.createResource(localId);
- else
- log.warn("Error reconstructing TransactionImpl instance for tx=" +
- toString() + " -- OTS resource factory missing." );
- }
-
- if (status == Status.STATUS_PREPARED)
- {
- if (registeredResource != null)
- {
- createPreparedTimeout();
- if (trace)
- log.trace("Calling replayCompletion " +
- "on the recovery coordinator, tx=" + toString());
- try
- {
- recoveryCoordinator.replayCompletion(registeredResource);
- }
- catch (NoSuchObjectException noCoordinator)
- {
- if (trace)
- {
- log.trace("Exception in replayCompletion: no coordinator for tx="
- + toString(), noCoordinator);
- log.trace("Rolling back transaction branch, tx=" + toString());
- }
- try
- {
- rollbackBranch();
- }
- catch (Exception e)
- {
- if (trace)
- log.trace("Exception in transaction branch rollback, tx=" +
- toString(), e);
- }
- }
- catch (Exception ignore)
- {
- if (trace)
- log.trace("Ignoring exception in replayCompletion, tx=" +
- toString(), ignore);
- }
- }
- else
- log.warn("Error reconstructing TransactionImpl instance for tx=" +
- toString() + " -- registeredResource not set.\n" +
- "The remote coordinator will NOT be contacted.");
- }
- else if (status == Status.STATUS_COMMITTING)
- {
- lock();
- try
- {
- retryCommitRemoteResources();
-
- if (preparedXAWorkList.size() > 0)
- {
- // Keep this TransactionImpl around to
- // commit its XAResources at a later time.
- commitXAResourcesAfterTimeout();
- }
- else if (remoteResourcesToRetry == 0 && heuristicCode == HEUR_NONE)
- {
- // This TransactionImpl is not needed anymore.
- completeTransaction();
- }
- else
- {
- // Do nothing. Just keep this TransactionImpl around to
- // receive replayCompletion calls from remote resources.
- }
- }
- finally
- {
- unlock();
- }
- }
- else if (status == Status.STATUS_ROLLING_BACK)
- {
- try
- {
- rollbackResourcesAndCompleteTransaction();
- }
- finally
- {
- unlock();
- }
- }
- }
-
- /**
- * Constructor to recreate a foreign transaction that entered this virtual
- * machine through JCA transaction inflow. This constructor is intended to
- * be called at recovery time, for recreating transactions that were in the
- * prepared state when the server crashed.
- *
- * @param localId the local id of a foreign transaction that entered this
- * virtual machine in a transaction propagation context and is
- * propagated along with a remote method invocation and is in
- * the prepared state
- * @param inboundFormatId format id part of the foreign <code>Xid</code>
- * @param globalTransactionId global id part of the foreign <code>Xid</code>
- * @param inboundBranchQualifier the branch qualifier part of the foreign
- * <code>Xid</code>
- * @param preparedXAWorkList a list of <code>org.jboss.tm.XAWork</code>
- * instances containing one element for each
- * <code>XAResource</code> enlisted with the transaction
- * @param resources an array with stringfied references for the remote
- * <code>Resource</code>s enlisted with the transaction
- * @param completionHandler the
- * <code>org.jboss.tm.recovery.TxCompletionHandler</code> to be
- * notifed when the second phase of the 2PC completes
- * @param heurData either null or a <code>LogRecord.HeurData</code> instance
- * contaning information on a locally-detected heuristic hazard.
- */
- TransactionImpl(long localId,
- int inboundFormatId,
- byte[] globalTransactionId,
- byte[] inboundBranchQualifier,
- List preparedXAWorkList,
- String[] resources,
- TxCompletionHandler completionHandler,
- LogRecord.HeurData heurData)
- {
- foreignTx = true;
- GlobalId globalId = new GlobalId(inboundFormatId, globalTransactionId);
- xid = xidFactory.recreateXid(localId, globalId);
- if (heurData == null)
- status = Status.STATUS_PREPARED;
- else
- {
- status = heurData.transactionStatus;
- heuristicCode = heurData.heuristicStatusCode;
- heuristicHazard = heurData.locallyDetectedHeuristicHazard;
- }
- this.inboundBranchQualifier = inboundBranchQualifier;
- this.completionHandler = completionHandler;
-
- for (Iterator it = preparedXAWorkList.iterator(); it.hasNext(); )
- {
- XAWork preparedXAWork = (XAWork) it.next();
- EnlistedXAResource r = new EnlistedXAResource(preparedXAWork);
- xaResources.add(r);
- }
-
- for (int i = 0; i < resources.length; i++)
- {
- EnlistedRemoteResource resource =
- new EnlistedRemoteResource(stringToResource(resources[i]), true);
- remoteResources.add(resource);
- }
-
- if (status == Status.STATUS_COMMITTING)
- {
- lock();
- try
- {
- retryCommitRemoteResources();
-
- if (xaResourcesToRetry > 0)
- {
- // Keep this TransactionImpl around to
- // commit its XAResources at a later time.
- commitXAResourcesAfterTimeout();
- }
- else if (remoteResourcesToRetry == 0 && heuristicCode == HEUR_NONE)
- {
- // This TransactionImpl is not needed anymore.
- completeTransaction();
- }
- else
- {
- // Do nothing. Just keep this TransactionImpl around to
- // receive replayCompletion calls from remote resources.
- }
- }
- finally
- {
- unlock();
- }
- }
- else if (status == Status.STATUS_ROLLING_BACK)
- {
- try
- {
- rollbackResourcesAndCompleteTransaction();
- }
- finally
- {
- unlock();
- }
- }
- }
-
- /**
- * Constructor to recreate a transaction that is in a heuristically
- * completed state (either committed or rolledback). This constructor is
- * intended to be called at recovery time, for recreating heuristically
- * completed transactions that were not yet forgotten when the server
- * crashed.
- *
- * @param heurData an instance of <code>LogRecord.HeurData</code> with
- * information on the heuristically completed transaction
- * @param xaResourcesWithHeuristics a list of
- * <code>org.jboss.tm.XAWork</code>
- * instances containing one element for each
- * <code>XAResource</code> that is in a a heuristic status
- * @param completionHandler the
- * <code>org.jboss.tm.recovery.TxCompletionHandler</code> to be
- * notifed when the second phase of the 2PC completes.
- */
- TransactionImpl(LogRecord.HeurData heurData,
- List xaResourcesWithHeuristics,
- TxCompletionHandler completionHandler)
- {
- foreignTx = heurData.foreignTx;
- status = heurData.transactionStatus;
-
- if (status != Status.STATUS_COMMITTING &&
- status != Status.STATUS_COMMITTED &&
- status != Status.STATUS_ROLLING_BACK &&
- status != Status.STATUS_ROLLEDBACK)
- throw new RuntimeException("Attempt to recreate heuristically " +
- "completed transaction with status " +
- TxUtils.getStatusAsString(status) + ". " +
- "Must be STATUS_COMMITTING, " +
- "STATUS_COMMITTED, STATUS_ROLLING_BACK, " +
- "or STATUS_ROLLEDBACK.");
- if (!foreignTx)
- xid = xidFactory.recreateXid(heurData.localTransactionId);
- else
- {
- GlobalId globalId = new GlobalId(heurData.formatId,
- heurData.globalTransactionId);
- xid = xidFactory.recreateXid(heurData.localTransactionId, globalId);
- }
- inboundBranchQualifier = heurData.inboundBranchQualifier;
- this.completionHandler = completionHandler;
- heuristicCode = heurData.heuristicStatusCode;
- if (!xaResourcesWithHeuristics.isEmpty())
- {
- xaResourcesWithHeuristicDecisions = new ArrayList();
- for (Iterator it = xaResourcesWithHeuristics.iterator();
- it.hasNext(); )
- {
- XAWork xaWork = (XAWork) it.next();
- xaWork.xaResourceAccess.release();
- EnlistedXAResource r = new EnlistedXAResource(
- xaWork.res,
- xaWork.xid,
- (heurData.transactionStatus == Status.STATUS_COMMITTED));
- xaResources.add(r);
- xaResourcesWithHeuristicDecisions.add(r);
- }
- }
- if (heurData.remoteResourceHeuristics != null &&
- heurData.remoteResourceHeuristics.length > 0)
- {
- remoteResourcesWithHeuristicDecisions = new ArrayList();
- for (int i = 0; i < heurData.remoteResourceHeuristics.length; i++)
- {
- HeuristicStatus heurStatus = heurData.remoteResourceHeuristics[i];
- EnlistedRemoteResource r =
- new EnlistedRemoteResource(
- stringToResource(heurStatus.resourceRef),
- true, /* committed */
- heurStatus.code);
- remoteResources.add(r);
- remoteResourcesWithHeuristicDecisions.add(r);
- }
- }
- }
-
- /**
- * Returns true if this is a foreign transaction and false if this is a
- * locally started transaction.
- *
- * @return true for a transaction that has been imported either through a
- * DTM/OTS transaction propagation context or through JCA
- * transaction inflow, and false for a locally started transaction.
- */
- public boolean isImported()
- {
- return foreignTx;
- }
-
- // Implements TimeoutTarget --------------------------------------
-
- /**
- * Called when our timeout expires.
- */
- public void timedOut(Timeout timeout)
- {
- lock();
- try
- {
- log.warn("Transaction " + toString() + " timed out." +
- " status=" + TxUtils.getStatusAsString(status));
-
- if (this.timeout == null)
- return; // Don't race with timeout cancellation.
- this.timeout = null;
-
- switch (status)
- {
- case Status.STATUS_ROLLEDBACK:
- case Status.STATUS_COMMITTED:
- case Status.STATUS_NO_TRANSACTION:
- return; // Transaction done.
-
- case Status.STATUS_ROLLING_BACK:
- return; // Will be done shortly.
-
- case Status.STATUS_PREPARED:
- case Status.STATUS_COMMITTING:
- return; // Timeout expiration has no effect anymore.
-
- case Status.STATUS_ACTIVE:
- status = Status.STATUS_MARKED_ROLLBACK;
- // fall through..
- case Status.STATUS_MARKED_ROLLBACK:
- // don't rollback for now, this messes up with the TxInterceptor.
- interruptThreads();
- return;
-
- case Status.STATUS_PREPARING:
- status = Status.STATUS_MARKED_ROLLBACK;
- return; // commit will fail
-
- default:
- log.warn("Unknown status at timeout, tx=" + toString());
- return;
- }
- }
- finally
- {
- unlock();
- }
- }
-
- // Implements Transaction ----------------------------------------
-
- public void commit()
- throws RollbackException,
- HeuristicMixedException,
- HeuristicRollbackException,
- java.lang.SecurityException,
- java.lang.IllegalStateException,
- SystemException
- {
- lock();
- try
- {
- if (trace)
- log.trace("Committing, tx=" + toString() +
- ", status=" + TxUtils.getStatusAsString(status));
-
- beforePrepare();
-
- if (status == Status.STATUS_ACTIVE)
- {
- switch (getCommitStrategy())
- {
- case 0:
- // Zero phase commit is really fast ;-)
- if (trace)
- log.trace("Zero phase commit " + toString() +
- ": No resources.");
- status = Status.STATUS_COMMITTED;
- break;
- case 1:
- // One phase commit
- if (trace)
- log.trace("One phase commit " + toString() +
- ": One resource.");
- commitResources(true);
- break;
- default:
- // Two phase commit
- if (trace)
- log.trace("Two phase commit " + toString() +
- ": Many resources.");
-
- if (!prepareResources())
- {
- boolean commitDecision =
- status == Status.STATUS_PREPARED &&
- (heuristicCode == HEUR_NONE ||
- heuristicCode == XAException.XA_HEURCOM);
-
- if (commitDecision)
- {
- // Save decision to stable storage
- // for recovery after system crash.
- try
- {
- RecoveryLogger logger =
- TxManager.getInstance().getRecoveryLogger();
- if (logger != null)
- {
- completionHandler = logger.saveCommitDecision(
- xid.getLocalIdValue(),
- getStringfiedRemoteResourcesThatVotedCommit());
- }
- }
- catch (Throwable e)
- {
- if (e instanceof RecoveryTestingException)
- throw (RecoveryTestingException) e;
- log.warn("FAILED WHEN WRITING COMMIT RECORD."
- + " Rolling back now.", e);
- status = Status.STATUS_MARKED_ROLLBACK;
- cause = e;
- }
- cancelTimeout();
- if (status == Status.STATUS_PREPARED)
- {
- try
- {
- commitResources(false);
- }
- catch (Throwable e)
- {
- if (e instanceof RecoveryTestingException)
- throw (RecoveryTestingException) e;
- log.warn("Unexpected exception in commitResources:",
- e);
- }
- }
- }
- }
- else
- status = Status.STATUS_COMMITTED; // all was read-only
- }
- }
-
- if (status == Status.STATUS_COMMITTING)
- {
- // Keep this TransactionImpl around.
- if (xaResourcesToRetry > 0)
- commitXAResourcesAfterTimeout();
- checkHeuristicsButDoNotThrowHeuristicHazard();
- }
- else if (status != Status.STATUS_COMMITTED)
- {
- Throwable causedByThrowable = cause;
- rollbackResourcesAndCompleteTransaction();
-
- // throw jboss rollback exception with the saved off cause
- throw new JBossRollbackException("Unable to commit, tx=" +
- toString() + ", status=" +
- TxUtils.getStatusAsString(status),
- causedByThrowable);
- }
- else /* (status == Status.STATUS_COMMITTED) */
- {
- cancelTimeout();
- doAfterCompletion();
- checkHeuristicsButDoNotThrowHeuristicHazard();
- instanceDone();
-
- if (trace)
- log.trace("Committed OK, tx=" + toString());
- }
- }
- finally
- {
- unlock();
- }
- }
-
- public void rollback()
- throws java.lang.IllegalStateException,
- java.lang.SecurityException,
- SystemException
- {
- lock();
- try
- {
-
- if (trace)
- log.trace("rollback(): Entered, tx=" + toString() +
- ", status=" + TxUtils.getStatusAsString(status));
-
- checkWork();
-
- switch (status)
- {
- case Status.STATUS_ACTIVE:
- status = Status.STATUS_MARKED_ROLLBACK;
- // fall through..
- case Status.STATUS_MARKED_ROLLBACK:
- endResources();
- rollbackResourcesAndCompleteTransaction();
- // Cannot throw heuristic exception, so we just have to
- // clear the heuristics without reporting.
- heuristicCode = HEUR_NONE;
- return;
- case Status.STATUS_PREPARING:
- // Set status to avoid race with prepareResources().
- status = Status.STATUS_MARKED_ROLLBACK;
- return; // commit() will do rollback.
- default:
- throw new IllegalStateException("Cannot rollback(), tx=" +
- toString() + ", status=" +
- TxUtils.getStatusAsString(status));
- }
- }
- finally
- {
- Thread.interrupted();// clear timeout that did an interrupt
- unlock();
- }
- }
-
- public boolean delistResource(XAResource xaRes, int flag)
- throws java.lang.IllegalStateException,
- SystemException
- {
- if (xaRes == null)
- throw new IllegalArgumentException("null xaRes tx=" + toString());
- if (flag != XAResource.TMSUCCESS &&
- flag != XAResource.TMSUSPEND &&
- flag != XAResource.TMFAIL)
- throw new IllegalArgumentException("Bad flag: " + flag +
- " tx=" + toString());
-
- lock();
- try
- {
- if (trace)
- log.trace("delistResource(): Entered, tx=" + toString() +
- ", status=" + TxUtils.getStatusAsString(status));
-
- EnlistedXAResource resource = findResource(xaRes);
- if (resource == null)
- throw new IllegalArgumentException("xaRes not enlisted " + xaRes);
-
- switch (status)
- {
- case Status.STATUS_ACTIVE:
- case Status.STATUS_MARKED_ROLLBACK:
- break;
- case Status.STATUS_PREPARING:
- throw new IllegalStateException("Already started preparing, tx=" +
- toString());
- case Status.STATUS_ROLLING_BACK:
- throw new IllegalStateException("Already started rolling back, tx="
- + toString());
- case Status.STATUS_PREPARED:
- throw new IllegalStateException("Already prepared, tx=" +
- toString());
- case Status.STATUS_COMMITTING:
- throw new IllegalStateException("Already started committing, tx=" +
- toString());
- case Status.STATUS_COMMITTED:
- throw new IllegalStateException("Already committed, tx=" +
- toString());
- case Status.STATUS_ROLLEDBACK:
- throw new IllegalStateException("Already rolled back, tx=" +
- toString());
- case Status.STATUS_NO_TRANSACTION:
- throw new IllegalStateException("No transaction, tx=" + toString());
- case Status.STATUS_UNKNOWN:
- throw new IllegalStateException("Unknown state, tx=" + toString());
- default:
- throw new IllegalStateException("Illegal status: " +
- TxUtils.getStatusAsString(status) +
- ", tx=" + toString());
- }
-
- try
- {
- return resource.delistResource(xaRes, flag);
- }
- catch (XAException xae)
- {
- logXAException(xae);
- status = Status.STATUS_MARKED_ROLLBACK;
- cause = xae;
- return false;
- }
- }
- finally
- {
- unlock();
- }
- }
-
- public boolean enlistResource(XAResource xaRes)
- throws RollbackException,
- java.lang.IllegalStateException,
- SystemException
- {
- if (xaRes == null)
- throw new IllegalArgumentException("null xaRes, tx=" + toString());
-
- lock();
- try
- {
- if (trace)
- log.trace("enlistResource(): Entered, tx=" + toString() +
- ", status=" + TxUtils.getStatusAsString(status) +
- ", xaRes=" + xaRes);
-
- checkStatus();
-
- if (resourcesEnded)
- throw new IllegalStateException("Too late to enlist resources, tx="
- + toString());
-
- // Add resource
- try
- {
- EnlistedXAResource resource = findResource(xaRes);
-
- // Existing resource
- if (resource != null)
- {
- if (resource.isEnlisted())
- {
- if (trace)
- log.trace("Already enlisted: tx=" + toString() +
- ", status=" + TxUtils.getStatusAsString(status) +
- ", xaRes=" + xaRes);
- return true; // already enlisted
- }
- if (resource.isDelisted(xaRes))
- // this is a resource that returns false on all calls to
- // isSameRM. Further, the last resource enlisted has
- // already been delisted, so it is time to enlist it again.
- resource = null;
- else
- return resource.startResource();
- }
-
- // Register itself as a resource with the parent coordinator
- if (parentCoordinator != null && recoveryCoordinator == null)
- registerResourceWithParentCoordinator();
-
- resource = findResourceManager(xaRes);
- if (resource != null)
- {
- // The xaRes is new. We register the xaRes with the Xid
- // that the RM has previously seen from this transaction,
- // and note that it has the same RM.
- resource = addResource(xaRes, resource.getXid(), resource);
- return resource.startResource();
- }
-
- // New resource and new RM: Create a new transaction branch.
- resource = addResource(xaRes, createXidBranch(), null);
- return resource.startResource();
- }
- catch (XAException xae)
- {
- logXAException(xae);
- cause = xae;
- return false;
- }
- }
- finally
- {
- unlock();
- }
-
- }
-
- public int getStatus()
- {
- if (done)
- return Status.STATUS_NO_TRANSACTION;
- return status;
- }
-
- public void registerSynchronization(Synchronization s)
- throws RollbackException,
- java.lang.IllegalStateException,
- SystemException
- {
- if (s == null)
- throw new IllegalArgumentException("Null synchronization, tx=" +
- toString());
-
- lock();
- try
- {
- if (trace)
- {
- log.trace("registerSynchronization(): Entered, " +
- "tx=" + toString() +
- ", status=" + TxUtils.getStatusAsString(status));
- }
-
- checkStatus();
-
- if (syncCount == syncAllocSize)
- {
- // expand table
- syncAllocSize = 2 * syncAllocSize;
-
- Synchronization[] sy = new Synchronization[syncAllocSize];
- System.arraycopy(sync, 0, sy, 0, syncCount);
- sync = sy;
- }
- sync[syncCount++] = s;
-
- // Register itself as a resource with the parent coordinator
- if (parentCoordinator != null && recoveryCoordinator == null)
- registerResourceWithParentCoordinator();
- }
- finally
- {
- unlock();
- }
- }
-
- public void setRollbackOnly()
- throws java.lang.IllegalStateException,
- SystemException
- {
- lock();
- try
- {
- if (trace)
- log.trace("setRollbackOnly(): Entered, tx=" + toString() +
- ", status=" + TxUtils.getStatusAsString(status));
-
- switch (status)
- {
- case Status.STATUS_ACTIVE:
- // Register itself as a resource with the parent coordinator
- if (parentCoordinator != null && recoveryCoordinator == null)
- {
- try
- {
- registerResourceWithParentCoordinator();
- }
- catch (RollbackException e)
- {
- log.warn("RollbackException in setRollbackOnly: " + e);
- }
- }
- // fall through..
- case Status.STATUS_PREPARING:
- case Status.STATUS_PREPARED:
- status = Status.STATUS_MARKED_ROLLBACK;
- // fall through..
- case Status.STATUS_MARKED_ROLLBACK:
- case Status.STATUS_ROLLING_BACK:
- return;
- case Status.STATUS_COMMITTING:
- throw new IllegalStateException("Already started committing, tx=" +
- toString());
- case Status.STATUS_COMMITTED:
- throw new IllegalStateException("Already committed, tx=" +
- toString());
- case Status.STATUS_ROLLEDBACK:
- throw new IllegalStateException("Already rolled back, tx=" +
- toString());
- case Status.STATUS_NO_TRANSACTION:
- throw new IllegalStateException("No transaction, tx=" + toString());
- case Status.STATUS_UNKNOWN:
- throw new IllegalStateException("Unknown state, tx=" + toString());
- default:
- throw new IllegalStateException("Illegal status: " +
- TxUtils.getStatusAsString(status) +
- ", tx=" + toString());
- }
- }
- finally
- {
- unlock();
- }
- }
-
- // Public methods called by DTM/OTS servants ---------------------
-
- /**
- * Enlists a remote DTM/OTS resource in this transaction. Called by the
- * DTM/OTS servants to implement the register resource method of the
- * DTM/OTS coordinator interface.
- *
- * @param remoteRes a remote DTM/OTS resource to be enlisted in this
- * transaction
- * @throws RollbackException
- * @throws java.lang.IllegalStateException
- *
- */
- public void enlistRemoteResource(Resource remoteRes)
- throws RollbackException,
- java.lang.IllegalStateException
- {
- if (remoteRes == null)
- throw new IllegalArgumentException("null remoteRes, tx=" + toString());
-
- lock();
- try
- {
- if (trace)
- log.trace("enlistRemoteResource(): Entered, tx=" + toString() +
- ", status=" + TxUtils.getStatusAsString(status));
-
- checkStatus();
-
- if (resourcesEnded)
- throw new IllegalStateException("Too late to enlist resources, tx="
- + toString());
-
- // Register itself as a resource with the parent coordinator
- if (parentCoordinator != null && recoveryCoordinator == null)
- registerResourceWithParentCoordinator();
-
- // Add resource
- EnlistedRemoteResource resource =
- new EnlistedRemoteResource(remoteRes);
- remoteResources.add(resource);
- }
- finally
- {
- unlock();
- }
- }
-
- /**
- * Prepare an external transaction
- *
- * @param inboundXid a foreign Xid that entered this VM via JCA transaction
- * inflow, or null in the case of an external transaction that
- * entered this VM in a transaction context propagated along with a
- * remote request.
- * @return XAResource.XA_RDONLY or XAResource.XA_OK
- */
- public int prepare(Xid inboundXid)
- throws HeuristicHazardException,
- HeuristicMixedException,
- HeuristicRollbackException,
- RollbackException
- {
- lock();
- try
- {
- if (trace)
- log.trace("Preparing, tx=" + toString() +
- ", status=" + TxUtils.getStatusAsString(status));
-
- checkWork();
-
- beforePrepare();
-
- if (status == Status.STATUS_ACTIVE)
- {
- switch (getCommitStrategy())
- {
- case 0:
- // Nothing to do, but we must be careful with synchronizations
- if (trace)
- log.trace("Prepare foreign tx=" + toString() +
- ": No resources.");
- if (syncCount == 0)
- {
- // No Synchronizations registered: we can vote read-only
- status = Status.STATUS_COMMITTED;
- completeTransaction();
- return XAResource.XA_RDONLY;
- }
- else
- { // There is at least one Synchronization registered:
- // vote commit so that afterCompletion gets called
- status = Status.STATUS_PREPARED;
- return XAResource.XA_OK;
- }
- default:
- // Two phase commit
- if (trace)
- log.trace("Prepare foreign tx=" + toString() +
- ": one or more resources.");
- if (!prepareResources())
- {
- boolean commitDecision =
- status == Status.STATUS_PREPARED &&
- (heuristicCode == HEUR_NONE ||
- heuristicCode == XAException.XA_HEURCOM);
-
- if (commitDecision)
- {
- // Save decision to stable storage
- // for recovery after system crash.
- try
- {
- RecoveryLogger logger =
- TxManager.getInstance().getRecoveryLogger();
- if (logger != null)
- {
- if (inboundXid == null)
- {
- completionHandler = logger.savePrepareDecision(
- xid.getLocalIdValue(),
- xid.getFormatId(),
- xid.getGlobalTransactionId(),
- recoveryCoordinatorToString(recoveryCoordinator),
- getStringfiedRemoteResourcesThatVotedCommit());
- }
- else
- {
- completionHandler = logger.savePrepareDecision(
- xid.getLocalIdValue(),
- inboundXid,
- getStringfiedRemoteResourcesThatVotedCommit());
- }
- }
- }
- catch (Throwable e)
- {
- if (e instanceof RecoveryTestingException)
- throw (RecoveryTestingException) e;
- log.warn("FAILED WHEN WRITING PREPARE RECORD."
- + " Rolling back now.");
- }
- }
- }
- else
- {
- if (syncCount == 0)
- {
- // No Synchronizations registered: we can vote read-only
- if (trace)
- log.trace("Prepared foreign tx=" + toString() +
- ": All readonly," +
- " no Synchronizations registered");
- status = Status.STATUS_COMMITTED;
- completeTransaction();
- return XAResource.XA_RDONLY;
- }
- else
- { // There is at least one Synchronization registered:
- // vote commit so that afterCompletion gets called
- if (trace)
- log.trace("Prepared foreign tx=" + toString() +
- ": All readonly, but there is at least" +
- " one Synchronization registered");
- status = Status.STATUS_PREPARED;
- return XAResource.XA_OK;
- }
- }
- break;
- }
- }
-
- if (status != Status.STATUS_PREPARED)
- {
- // save off the cause throwable as
- // instanceDone resets it to null
- Throwable causedByThrowable = cause;
- rollbackResourcesAndCompleteTransaction();
-
- // throw jboss rollback exception with the saved off cause
- throw new JBossRollbackException("Unable to prepare, tx=" +
- toString() + ", status=" +
- TxUtils.getStatusAsString(status),
- causedByThrowable);
- }
-
- if (inboundXid == null)
- createPreparedTimeout();
-
- // We are ok to commit
- return XAResource.XA_OK;
- }
- finally
- {
- unlock();
- }
- }
-
- /**
- * Commit an external transaction
- *
- * @param onePhase whether the commit is one or two phase
- */
- public void commit(boolean onePhase)
- throws RollbackException,
- HeuristicHazardException,
- HeuristicMixedException,
- HeuristicRollbackException,
- SystemException
- {
- checkWork();
-
- // One phase commit optimization
- if (onePhase)
- {
- commit();
- return;
- }
-
- // Two phase
- lock();
- try
- {
- if (trace)
- log.trace("Committing two phase, tx=" + toString() +
- ", status=" + TxUtils.getStatusAsString(status));
-
- cancelPreparedTimeout();
-
- switch (status)
- {
- case Status.STATUS_PREPARING:
- throw new IllegalStateException("Still preparing, tx=" +
- toString());
- case Status.STATUS_ROLLING_BACK:
- throw new IllegalStateException("Already started rolling back, tx="
- + toString());
- case Status.STATUS_ROLLEDBACK:
- instanceDone();
- //checkHeuristics();
- throw new IllegalStateException("Already rolled back, tx=" +
- toString());
- case Status.STATUS_COMMITTING:
- if (trace)
- log.trace("Already committing, tx=" + toString());
- return;
- case Status.STATUS_COMMITTED:
- instanceDone();
- //checkHeuristics();
- if (trace)
- log.trace("Already committed, tx=" + toString());
- return;
- case Status.STATUS_NO_TRANSACTION:
- throw new IllegalStateException("No transaction, tx=" + toString());
- case Status.STATUS_UNKNOWN:
- throw new IllegalStateException("Unknown state, tx=" + toString());
- case Status.STATUS_MARKED_ROLLBACK:
- endResources();
- rollbackResourcesAndCompleteTransaction();
- checkHeuristics();
- throw new RollbackException("Already marked for rollback, tx=" +
- toString());
- case Status.STATUS_PREPARED:
- break;
- default:
- throw new IllegalStateException("Illegal status: " +
- TxUtils.getStatusAsString(status) +
- ", tx=" + toString());
- }
-
- commitResources(false);
-
- if (status == Status.STATUS_COMMITTING)
- {
- // Keep this TransactionImpl around.
- if (xaResourcesToRetry > 0)
- commitXAResourcesAfterTimeout();
- checkHeuristics();
- }
- else if (status != Status.STATUS_COMMITTED)
- {
- Throwable causedByThrowable = cause;
-
- // throw jboss rollback exception with the saved off cause
- throw new JBossRollbackException("Unable to commit, tx=" +
- toString() + ", status=" +
- TxUtils.getStatusAsString(status),
- causedByThrowable);
- }
- else /* (status == Status.STATUS_COMMITTED) */
- {
- cancelTimeout();
- doAfterCompletion();
- checkHeuristics();
- instanceDone();
-
- if (trace)
- log.trace("Committed OK, tx=" + toString());
- }
- }
- finally
- {
- unlock();
- }
- }
-
- /**
- * Rollback an external transaction
- */
- public void rollbackBranch()
- throws HeuristicCommitException,
- HeuristicMixedException,
- HeuristicHazardException,
- java.lang.IllegalStateException
- {
- lock();
- try
- {
-
- if (trace)
- log.trace("rollbackBranch(): Entered, tx=" + toString() +
- ", status=" + TxUtils.getStatusAsString(status));
-
- checkWork();
- cancelPreparedTimeout();
-
- switch (status)
- {
- case Status.STATUS_ACTIVE:
- case Status.STATUS_PREPARED:
- status = Status.STATUS_MARKED_ROLLBACK;
- // fall through..
- case Status.STATUS_MARKED_ROLLBACK:
- endResources();
- rollbackResourcesAndCompleteTransaction();
- switch (getFullHeuristicCode())
- {
- case XAException.XA_HEURHAZ:
- if (trace)
- log.trace("Throwing HeuristicHazardException, tx=" +
- toString() + ", status=" +
- TxUtils.getStatusAsString(status));
- throw new HeuristicHazardException();
- case XAException.XA_HEURMIX:
- if (trace)
- log.trace("Throwing HeuristicMixedException, tx=" +
- toString() + ", status=" +
- TxUtils.getStatusAsString(status));
- throw new HeuristicMixedException();
- case XAException.XA_HEURRB:
- if (trace)
- log.trace("Not throwing HeuristicRollbackException, tx=" +
- toString() + ", status=" +
- TxUtils.getStatusAsString(status));
- break;
- case XAException.XA_HEURCOM:
- if (trace)
- log.trace("Throwing HeuristicCommitException, tx=" +
- toString() + ", status=" +
- TxUtils.getStatusAsString(status));
- throw new HeuristicCommitException();
- }
- return;
- case Status.STATUS_PREPARING:
- // Set status to avoid race with prepareResources().
- status = Status.STATUS_MARKED_ROLLBACK;
- return; // commit() will do rollback.
- case Status.STATUS_ROLLEDBACK:
- if (trace)
- log.trace("Already rolledback, tx=" + toString());
- return;
- default:
- throw new IllegalStateException("Cannot rollback(), tx=" +
- toString() + ", status=" +
- TxUtils.getStatusAsString(status));
- }
- }
- finally
- {
- Thread.interrupted();// clear timeout that did an interrupt
- unlock();
- }
- }
-
- /**
- * Forgets the heuristic status of the transaction. This method should
- * be called on heuristically completed transactions.
- */
- public void forget()
- {
- lock();
- try {
- if (heuristicCode == HEUR_NONE && !heuristicHazard)
- return;
-
- if (status != Status.STATUS_COMMITTED &&
- status != Status.STATUS_ROLLEDBACK &&
- (status != Status.STATUS_COMMITTING || !heuristicHazard) &&
- (status != Status.STATUS_ROLLING_BACK || !heuristicHazard))
- return;
-
- if (forgetResources())
- {
- // Clear heuristics status from stable storage
- RecoveryLogger logger = TxManager.getInstance().getRecoveryLogger();
- if (logger != null)
- {
- logger.clearHeuristicStatus(xid.getLocalIdValue());
- if (status == Status.STATUS_COMMITTED &&
- completionHandler != null)
- completionHandler.handleTxCompletion(xid.getLocalIdValue());
- }
- instanceDone();
- }
- }
- finally
- {
- unlock();
- }
- }
-
- /**
- * If this transaction is in the committing state, this method starts
- * a thread that calls commit on the remote resources that were not yet
- * successful committed. It returns the current status of the transaction
- * (before any commit calls are issued).
- *
- * @return the current status of the transaction.
- */
- public int replayCompletion(final Resource r)
- {
- lock();
- try
- {
- if (status != Status.STATUS_MARKED_ROLLBACK &&
- status != Status.STATUS_ROLLING_BACK &&
- status != Status.STATUS_ROLLEDBACK)
- {
- final boolean pendingCommits =
- (status == Status.STATUS_COMMITTING &&
- remoteResourcesToRetry > 0);
-
- Runnable runnable = new Runnable()
- {
- public void run()
- {
- try
- {
- if (trace)
- log.trace("Replay completion thread: " +
- " committing remote resource " + r);
- r.commit();
-
- if (trace)
- log.trace("Replay completion thread: " +
- " committed remote resource " + r);
- }
- catch (Throwable ignored)
- {
- if (trace)
- log.trace("Replay completion thread: ignored exception"
- + " when committing remote resource " + r ,
- ignored);
- }
-
- if (pendingCommits)
- {
- lock();
- try
- {
- if (trace)
- log.trace("Replay completion thread: calling " +
- "retryCommitRemoteResources");
-
- retryCommitRemoteResources();
- if (xaResourcesToRetry == 0 &&
- remoteResourcesToRetry == 0 &&
- heuristicCode == HEUR_NONE)
- completeTransaction();
- }
- finally
- {
- unlock();
- }
- }
- if (trace)
- log.trace("Replay completion thread: exiting");
- }
- };
- Thread t = new Thread(runnable, "replayCompletionThread");
-
- t.start();
- }
- return status;
- }
- finally
- {
- unlock();
- }
- }
-
- /**
- * DTM/OTS servants need this method to implement the get transaction
- * propagation context method of the coordinator interface.
- *
- * @param errorRollback throw a RollbackException if the transaction is
- * not active
- * @return the time left before this transaction time-out expires.
- * @throws RollbackException if the transaction is not active and
- * errorRollback is true.
- */
- public long getTimeLeftBeforeTimeout(boolean errorRollback)
- throws RollbackException
- {
- if (errorRollback && status != Status.STATUS_ACTIVE)
- throw new RollbackException("Transaction is not active: " +
- TxUtils.getStatusAsString(status));
- return (start + timeoutPeriod) - System.currentTimeMillis();
- }
-
- public int getAssociatedThreadCount()
- {
- lock();
- try
- {
- return threads.size();
- }
- finally
- {
- unlock();
- }
- }
-
- public Set getAssociatedThreads()
- {
- lock();
- try
- {
- return Collections.unmodifiableSet(threads);
- }
- finally
- {
- unlock();
- }
- }
-
- public int hashCode()
- {
- return xid.hashCode();
- }
-
- public String toString()
- {
- return "TransactionImpl:" + xidFactory.toString(xid);
- }
-
- public boolean equals(Object obj)
- {
- if (obj != null && obj instanceof TransactionImpl)
- return getLocalIdValue() == (((TransactionImpl) obj).getLocalIdValue());
- return false;
- }
-
-
- /**
- * Returns the local id of this transaction. The local id is used as
- * a transaction propagation context within the JBoss server, and
- * in the TxManager for mapping local transaction ids to transactions.
- */
- public long getLocalIdValue()
- {
- return xid.getLocalIdValue();
- }
-
- /**
- * Returns the local id of this transaction. The local id is used as
- * a transaction propagation context within the JBoss server, and
- * in the TxManager for mapping local transaction ids to transactions.
- */
- public LocalId getLocalId()
- {
- return xid.getLocalId();
- }
-
- /**
- * Returns the global id of this transaction. Ths global id is used in
- * the TxManager, which keeps a map from global ids to transactions.
- */
- public GlobalId getGlobalId()
- {
- return xid.getTrulyGlobalId();
- }
-
- /**
- * Returns the xid of this transaction.
- */
- public XidImpl getXid()
- {
- return xid;
- }
-
- /**
- * Returns this transaction's DTM propagation context.
- */
- public TxPropagationContext getPropagationContext()
- {
- if (dtmPropagationContext == null)
- {
- Coordinator coordinatorToPropagate;
-
- if (parentCoordinator == null || interpositionEnabled ||
- !Proxy.isProxyClass(parentCoordinator.getClass()))
- {
- // no parent coordinator, or interposition enabled, or
- // parent coordinator is a wrapped OTS coordinator:
- // propagate proxy to a local DTM coordinator
- coordinatorToPropagate =
- dtmCoordinatorFactory.createCoordinator(getLocalIdValue());
- }
- else
- {
- // parent coordinator is a DTM coordinator and interposition is
- // disabled: propagate the parent coordinator
- coordinatorToPropagate = parentCoordinator;
- }
-
- // Create TxPropagationContext
- dtmPropagationContext =
- new TxPropagationContext(xid.getFormatId(),
- xid.getGlobalTransactionId(),
- 0, /* timeout set below */
- coordinatorToPropagate,
- null /* null Terminator */);
- }
-
- // Update the timeout in the TPC and return the TPC
- try
- {
- dtmPropagationContext.timeout =
- TMUtil.divideAndRoundUp(getTimeLeftBeforeTimeout(true), 1000);
- }
- catch (RollbackException transactionNotActive)
- {
- if (status == Status.STATUS_MARKED_ROLLBACK)
- dtmPropagationContext.timeout = 0;
- else
- dtmPropagationContext = null;
- }
- return dtmPropagationContext;
- }
-
- /**
- * Returns this transaction's OTS propagation context.
- */
- public Object getOTSPropagationContext()
- {
- if (otsPropagationContext == null)
- {
- if (parentCoordinator == null || interpositionEnabled ||
- Proxy.isProxyClass(parentCoordinator.getClass()))
- {
- // no parent coordinator, or interposition enabled, or
- // parent coordinator is a dynamic proxy (rather than a wrapped
- // OTS coordinator): propagate reference to a local OTS coordinator
- otsPropagationContext =
- otsContextFactory.createOTSContext(xid.getFormatId(),
- xid.getGlobalTransactionId(),
- getLocalIdValue());
- }
- else
- {
- // parent coordinator is a DTM coordinator and interposition is
- // disabled: propagate the parent coordinator
- otsPropagationContext =
- otsContextFactory.createOTSContext(xid.getFormatId(),
- xid.getGlobalTransactionId(),
- parentCoordinator);
- }
- }
-
- // Update the timeout in the TPC and return the TPC
- try
- {
- otsContextFactory.setTimeout(
- otsPropagationContext,
- TMUtil.divideAndRoundUp(getTimeLeftBeforeTimeout(true), 1000));
- }
- catch (RollbackException transactionNotActive)
- {
- if (status == Status.STATUS_MARKED_ROLLBACK)
- otsContextFactory.setTimeout(otsPropagationContext, 0);
- else
- otsPropagationContext = null;
- }
- return otsPropagationContext;
- }
-
- public void setHeuristicStatus(LogRecord.HeurData heurData)
- {
- lock();
- try
- {
- if (status != heurData.transactionStatus)
- {
- if (status == Status.STATUS_PREPARED)
- cancelPreparedTimeout();
-
- status = heurData.transactionStatus;
-
- if (status == Status.STATUS_COMMITTING)
- {
- retryCommitRemoteResources();
-
- if (xaResourcesToRetry > 0)
- {
- // Keep this TransactionImpl around to
- // commit its XAResources at a later time.
- commitXAResourcesAfterTimeout();
- }
- else if (remoteResourcesToRetry == 0 && heuristicCode == HEUR_NONE)
- {
- // This TransactionImpl is not needed anymore.
- completeTransaction();
- }
- else
- {
- // Do nothing. Just keep this TransactionImpl around to
- // receive replayCompletion calls from remote resources.
- }
- }
- else if (status == Status.STATUS_ROLLING_BACK)
- {
- rollbackResourcesAndCompleteTransaction();
- }
- }
- }
- finally
- {
- unlock();
- }
- }
-
- // Package protected ---------------------------------------------
-
- /**
- * Checks whether this transaction is a foreign transaction that entered
- * the server via JCA transaction inflow and is either in the prepared state
- * or in a heuristically completed state.
- *
- * @return true if this is a JCA inbound transaction that is either prepared
- * or heuristically completed (but not yet forgotten), false
- * otherwise.
- */
- boolean isPreparedOrHeuristicallyCompletedJCAInboundTx()
- {
- return inboundBranchQualifier != null
- && (status == Status.STATUS_PREPARED
- || (getFullHeuristicCode() != HEUR_NONE
- && (status == Status.STATUS_COMMITTED
- || status == Status.STATUS_ROLLEDBACK)));
- }
-
- /**
- * Gets the inbound <code>Xid</code> of a foreign transaction that entered
- * the server via JCA transaction inflow.
- *
- * @return the inbound <code>Xid</code>.
- */
- Xid getInboundXid()
- {
- return new Xid()
- {
- public int getFormatId()
- {
- return xid.getFormatId();
- }
-
- public byte[] getGlobalTransactionId()
- {
- return xid.getGlobalTransactionId();
- }
-
- public byte[] getBranchQualifier()
- {
- return (byte[])inboundBranchQualifier.clone();
- }
- };
- }
-
- void associateCurrentThread()
- {
- Thread.interrupted();
- lock();
- try
- {
- threads.add(Thread.currentThread());
- }
- finally
- {
- unlock();
- }
- }
-
- void disassociateCurrentThread()
- {
- // Just a tidyup, no need to synchronize
- if (done)
- {
- threads.remove(Thread.currentThread());
- }
- else
- {
- // Removing the association for an active transaction
- lock();
- try
- {
- threads.remove(Thread.currentThread());
- }
- finally
- {
- unlock();
- }
- }
- Thread.interrupted();
- }
-
- /**
- * Lock this instance.
- */
- synchronized void lock()
- {
- if (done)
- throw new IllegalStateException("Transaction has terminated, tx=" +
- toString());
-
- Thread currentThread = Thread.currentThread();
- if (locked != null && locked != currentThread)
- {
- log.debug("Lock contention, tx=" + toString() +
- " otherThread=" + locked);
- //DEBUG Thread.currentThread().dumpStack();
-
- while (locked != null && locked != currentThread)
- {
- try
- {
- // Wakeup happens when:
- // - notify() is called from unlock()
- // - notifyAll is called from instanceDone()
- wait();
- }
- catch (InterruptedException ex)
- {
- // ignore
- }
-
- if (done)
- throw new IllegalStateException(
- "Transaction has now terminated, tx=" + toString());
- }
- }
-
- locked = currentThread;
- ++lockDepth;
- }
-
- /**
- * Unlock this instance.
- */
- synchronized void unlock()
- {
- Thread currentThread = Thread.currentThread();
- if (locked == null || locked != currentThread)
- {
- log.warn("Unlocking, but not locked, tx=" + toString() +
- " otherThread=" + locked,
- new Throwable("[Stack trace]"));
- }
- else
- {
- if (--lockDepth == 0)
- {
- locked = null;
- notify();
- }
- }
- }
-
- /**
- * Deactivate this transaction.
- */
- synchronized void deactivate()
- {
- lock();
- try
- {
- cancelTimeout();
- cancelPreparedTimeout();
- cancelXARetryTimeout();
-
- // Clear tables refering to external objects.
- // Even if a client holds on to this instance forever, the objects
- // that we have referenced may be garbage collected.
- parentCoordinator = null;
- sync = null;
- xaResources = null;
- remoteResources = null;
- transactionLocalMap.clear();
- threads.clear();
-
- // Set the status
- status = Status.STATUS_NO_TRANSACTION;
-
- // Notify all threads waiting for the lock.
- notifyAll();
-
- // set the done flag
- done = true;
- }
- finally
- {
- unlock();
- }
- }
-
- /**
- * Get the work
- *
- * @return the work
- */
- Work getWork()
- {
- return work;
- }
-
- /**
- * Set the work
- *
- * @param work the work
- * @throws WorkCompletedException with error code WorkException.TX_CONCURRENT_WORK_DISALLOWED
- * when work is already present for the xid or whose completion is in progress, only
- * the global part of the xid must be used for this check. Or with error code
- * WorkException.TX_RECREATE_FAILED if it is unable to recreate the transaction context
- */
- void setWork(Work work)
- throws WorkCompletedException
- {
- lock();
- try
- {
- if (work == null)
- {
- this.work = null;
- return;
- }
-
- if (status == Status.STATUS_NO_TRANSACTION || status == Status.STATUS_UNKNOWN)
- throw new WorkCompletedException("The transaction is not active " +
- toString() + ": " +
- TxUtils.getStatusAsString(status),
- WorkException.TX_RECREATE_FAILED);
- else if (status != Status.STATUS_ACTIVE)
- throw new WorkCompletedException("Too late to start work " +
- toString() + ": " +
- TxUtils.getStatusAsString(status),
- WorkException.TX_CONCURRENT_WORK_DISALLOWED);
- else if (this.work != null)
- throw new WorkCompletedException("Already have work " + toString() +
- ": " + this.work,
- WorkException.TX_CONCURRENT_WORK_DISALLOWED);
-
- this.work = work;
- }
- finally
- {
- unlock();
- }
- }
-
- /**
- * Getter for property done.
- */
- boolean isDone()
- {
- return done || (heuristicCode != HEUR_NONE &&
- (status == Status.STATUS_COMMITTING ||
- status == Status.STATUS_COMMITTED ||
- status == Status.STATUS_ROLLING_BACK ||
- status == Status.STATUS_ROLLEDBACK));
- }
-
- Object getTransactionLocalValue(TransactionLocal tlocal)
- {
- return transactionLocalMap.get(tlocal);
- }
-
- void putTransactionLocalValue(TransactionLocal tlocal, Object value)
- {
- transactionLocalMap.put(tlocal, value);
- }
-
- boolean containsTransactionLocal(TransactionLocal tlocal)
- {
- return transactionLocalMap.containsKey(tlocal);
- }
-
- // Private -------------------------------------------------------
-
- /**
- * Before prepare
- */
- private void beforePrepare()
- throws HeuristicMixedException,
- HeuristicRollbackException,
- RollbackException
- {
- checkIntegrity();
-
- doBeforeCompletion();
-
- if (trace)
- log.trace("Before completion done, tx=" + toString() +
- ", status=" + TxUtils.getStatusAsString(status));
-
- endResources();
- }
-
- /**
- * Check the integrity of the transaction
- */
- private void checkIntegrity()
- throws HeuristicMixedException,
- HeuristicRollbackException,
- RollbackException
- {
- // Spec defined checks for the transaction in a valid state
- checkBeforeStatus();
-
- TransactionIntegrity integrity = TxManager.getInstance().getTransactionIntegrity();
- if (integrity != null)
- {
- // Extra integrity checks
- unlock();
- try
- {
- integrity.checkTransactionIntegrity(this);
- }
- finally
- {
- lock();
- }
-
- // Recheck the transaction state
- checkBeforeStatus();
- }
- }
-
- /**
- * Check the before status
- */
- private void checkBeforeStatus()
- throws HeuristicMixedException,
- HeuristicRollbackException,
- RollbackException
- {
- switch (status)
- {
- case Status.STATUS_PREPARING:
- throw new IllegalStateException("Already started preparing, tx=" +
- toString());
- case Status.STATUS_PREPARED:
- throw new IllegalStateException("Already prepared, tx=" + toString());
- case Status.STATUS_ROLLING_BACK:
- throw new IllegalStateException("Already started rolling back, tx=" +
- toString());
- case Status.STATUS_ROLLEDBACK:
- instanceDone();
- //checkHeuristics();
- throw new IllegalStateException("Already rolled back, tx=" +
- toString());
- case Status.STATUS_COMMITTING:
- throw new IllegalStateException("Already started committing, tx=" +
- toString());
- case Status.STATUS_COMMITTED:
- instanceDone();
- //checkHeuristics();
- throw new IllegalStateException("Already committed, tx=" + toString());
- case Status.STATUS_NO_TRANSACTION:
- throw new IllegalStateException("No transaction, tx=" + toString());
- case Status.STATUS_UNKNOWN:
- throw new IllegalStateException("Unknown state, tx=" + toString());
- case Status.STATUS_MARKED_ROLLBACK:
- endResources();
- rollbackResourcesAndCompleteTransaction();
- checkHeuristicsButDoNotThrowHeuristicHazard();
- throw new RollbackException("Already marked for rollback, tx=" +
- toString());
- case Status.STATUS_ACTIVE:
- break;
- default:
- throw new IllegalStateException("Illegal status: " +
- TxUtils.getStatusAsString(status) +
- ", tx=" + toString());
- }
- }
-
- /**
- * Complete the transaction
- */
- private void completeTransaction()
- {
- cancelTimeout();
- doAfterCompletion();
- instanceDone();
- }
-
- /**
- * Checks if the transaction state allows calls to the methods
- * <code>enlistResource</code> and <code>registerSynchronization</code>
- *
- * @throws RollbackException
- * @throws IllegalStateException
- */
- private void checkStatus()
- throws RollbackException
- {
- switch (status)
- {
- case Status.STATUS_ACTIVE:
- case Status.STATUS_PREPARING:
- break;
- case Status.STATUS_PREPARED:
- throw new IllegalStateException("Already prepared, tx=" + toString());
- case Status.STATUS_COMMITTING:
- throw new IllegalStateException("Already started committing, tx=" +
- toString());
- case Status.STATUS_COMMITTED:
- throw new IllegalStateException("Already committed, tx=" + toString());
- case Status.STATUS_MARKED_ROLLBACK:
- throw new RollbackException("Already marked for rollback, tx=" +
- toString());
- case Status.STATUS_ROLLING_BACK:
- throw new RollbackException("Already started rolling back, tx=" +
- toString());
- case Status.STATUS_ROLLEDBACK:
- throw new RollbackException("Already rolled back, tx=" + toString());
- case Status.STATUS_NO_TRANSACTION:
- throw new IllegalStateException("No transaction, tx=" + toString());
- case Status.STATUS_UNKNOWN:
- throw new IllegalStateException("Unknown state, tx=" + toString());
- default:
- throw new IllegalStateException("Illegal status: " +
- TxUtils.getStatusAsString(status) +
- ", tx=" + toString());
- }
- }
-
- /**
- * Interrupt all threads involved with transaction
- * This is called on timeout
- */
- private void interruptThreads()
- {
- TxManager manager = TxManager.getInstance();
- if (manager.isInterruptThreads())
- {
- HashSet clone = (HashSet) threads.clone();
- threads.clear();
- for (Iterator i = clone.iterator(); i.hasNext();)
- {
- Thread thread = (Thread) i.next();
- try
- {
- thread.interrupt();
- }
- catch (Throwable ignored)
- {
- if (trace)
- log.trace("Ignored error interrupting thread: " +
- thread, ignored);
- }
- }
- }
- }
-
- private void logXAException(XAException xae)
- {
- log.warn("XAException: tx=" + toString() + " errorCode=" +
- TxUtils.getXAErrorCodeAsString(xae.errorCode), xae);
- if (xaExceptionFormatter != null)
- xaExceptionFormatter.formatXAException(xae, log);
- }
-
- /**
- * Mark this transaction as non-existing.
- */
- private synchronized void instanceDone()
- {
- TxManager manager = TxManager.getInstance();
-
- if (status == Status.STATUS_COMMITTED)
- manager.incCommitCount();
- else
- manager.incRollbackCount();
-
- // Clear tables refering to external objects.
- // Even if a client holds on to this instance forever, the objects
- // that we have referenced may be garbage collected.
- parentCoordinator = null;
- sync = null;
- xaResources = null;
- remoteResources = null;
- transactionLocalMap.clear();
- threads.clear();
-
- // Garbage collection
- manager.releaseTransactionImpl(this);
-
- // Set the status
- status = Status.STATUS_NO_TRANSACTION;
-
- // Notify all threads waiting for the lock.
- notifyAll();
-
- // set the done flag
- done = true;
- }
-
- /**
- * Cancel the timeout.
- * This will release the lock while calling out.
- */
- private void cancelTimeout()
- {
- if (timeout != null)
- {
- unlock();
- try
- {
- timeout.cancel();
- }
- catch (Exception e)
- {
- if (trace)
- log.trace("failed to cancel timeout, tx=" + toString(), e);
- }
- finally
- {
- lock();
- }
- timeout = null;
- }
- }
-
- /**
- * Create prepared timeout.
- */
- private void createPreparedTimeout()
- {
- preparedTimeout = timeoutFactory.createTimeout(
- System.currentTimeMillis() +
- TxManager.getInstance().getPreparedTimeoutMillis(),
- new TimeoutTarget()
- {
- public void timedOut(Timeout timeout)
- {
- if (trace)
- log.trace("Prepared timeout expired for tx=" +
- TransactionImpl.this.toString() +
- ", calling replayCompletion " +
- "on the recovery coordinator");
- try
- {
- recoveryCoordinator.replayCompletion(registeredResource);
- }
- catch (NoSuchObjectException noCoordinator)
- {
- if (trace)
- {
- log.trace("Exception in replayCompletion: " +
- "no coordinator for tx=" + toString(),
- noCoordinator);
- log.trace("Rolling back transaction branch, tx=" +
- TransactionImpl.this.toString());
- }
- try
- {
- rollbackBranch();
- }
- catch (Exception e)
- {
- if (trace)
- log.trace("Exception in transaction branch rollback,"
- + " tx=" + TransactionImpl.this.toString(),
- e);
-
- }
- }
- catch (Exception ignore)
- {
- if (trace)
- log.trace("Ignoring exception in replayCompletion, tx="
- + TransactionImpl.this.toString(), ignore);
- }
- if (!done)
- {
- lock();
- try
- {
- if (preparedTimeout != null)
- {
- preparedTimeout = timeoutFactory.createTimeout(
- System.currentTimeMillis() +
- TxManager.getInstance()
- .getPreparedTimeoutMillis(),
- this);
- }
- }
- finally
- {
- unlock();
- }
- }
- }
- });
- }
-
- /**
- * Cancel prepared timeout.
- */
- private void cancelPreparedTimeout()
- {
- if (preparedTimeout != null)
- {
- Timeout pt = preparedTimeout;
- preparedTimeout = null;
-
- unlock();
- try
- {
- pt.cancel();
- }
- catch (Exception e)
- {
- if (trace)
- log.trace("failed to cancel prepared timeout, tx=" + toString(),
- e);
- }
- finally
- {
- lock();
- }
- }
- }
-
- /**
- * Return the resource for the given XAResource
- */
- private EnlistedXAResource findResource(XAResource xaRes)
- {
- // A linear search may seem slow, but please note that
- // the number of XA resources registered with a transaction
- // are usually low.
- // Note: This searches backwards intentionally! It ensures that
- // if this resource was enlisted multiple times, then the last one
- // will be returned. All others should be in the state RS_ENDED.
- // This allows ResourceManagers that always return false from isSameRM
- // to be enlisted and delisted multiple times.
- for (int idx = xaResources.size() - 1; idx >= 0; --idx)
- {
- EnlistedXAResource resource =
- (EnlistedXAResource) xaResources.get(idx);
- if (xaRes == resource.getXAResource())
- return resource;
- }
-
- return null;
- }
-
- private EnlistedXAResource findResourceManager(XAResource xaRes)
- throws XAException
- {
- for (int i = 0; i < xaResources.size(); ++i)
- {
- EnlistedXAResource resource = (EnlistedXAResource) xaResources.get(i);
- if (resource.isResourceManager(xaRes))
- return resource;
- }
- return null;
- }
-
- /**
- * Add a resource, expanding tables if needed.
- *
- * @param xaRes The new XA resource to add. It is assumed that the
- * resource is not already in the table of XA resources.
- * @param branchXid The Xid for the transaction branch that is to
- * be used for associating with this resource.
- * @param sameRMResource The resource of the first
- * XA resource having the same resource manager as
- * <code>xaRes</code>, or <code>null</code> if <code>xaRes</code>
- * is the first resource seen with this resource manager.
- * @return the new resource
- */
- private EnlistedXAResource addResource(XAResource xaRes,
- Xid branchXid,
- EnlistedXAResource sameRMResource)
- {
- EnlistedXAResource resource =
- new EnlistedXAResource(xaRes, branchXid, sameRMResource);
- xaResources.add(resource);
-
- // Remember the first resource that wants the last resource gambit
- if (lastResource == null && xaRes instanceof LastResource)
- lastResource = resource;
-
- return resource;
- }
-
- /**
- * End Tx association for all resources.
- */
- private void endResources()
- {
- for (int idx = 0; idx < xaResources.size(); ++idx)
- {
- EnlistedXAResource resource =
- (EnlistedXAResource) xaResources.get(idx);
- try
- {
- resource.endResource();
- }
- catch (XAException xae)
- {
- logXAException(xae);
- status = Status.STATUS_MARKED_ROLLBACK;
- cause = xae;
- }
- }
- resourcesEnded = true; // Too late to enlist new resources.
- }
-
-
- /**
- * Call synchronization <code>beforeCompletion()</code>.
- * This will release the lock while calling out.
- */
- private void doBeforeCompletion()
- {
- unlock();
- try
- {
- for (int i = 0; i < syncCount; i++)
- {
- try
- {
- if (trace)
- log.trace("calling sync " + i + ", " + sync[i] +
- " tx=" + toString());
-
- sync[i].beforeCompletion();
- }
- catch (Throwable t)
- {
- if (trace)
- log.trace("failed before completion " + sync[i], t);
-
- status = Status.STATUS_MARKED_ROLLBACK;
-
- // save the cause off so the user can inspect it
- cause = t;
- break;
- }
- }
- }
- finally
- {
- lock();
- }
- }
-
- /**
- * Call synchronization <code>afterCompletion()</code>.
- * This will release the lock while calling out.
- */
- private void doAfterCompletion()
- {
- // Assert: Status indicates: Too late to add new synchronizations.
- unlock();
- try
- {
- for (int i = 0; i < syncCount; i++)
- {
- try
- {
- sync[i].afterCompletion(status);
- }
- catch (Throwable t)
- {
- if (trace)
- log.trace("failed after completion " + sync[i], t);
- }
- }
- }
- finally
- {
- lock();
- }
- }
-
- /**
- * Groups two heuristic codes into a composite code.
- *
- * @param code1 a heuristic code (one of
- * <code>XAException.XA_HEURxxx</code>)
- * @param code2 another heuristic code
- * @return the composite heuristic code.
- */
- private static int groupHeuristics(int code1, int code2)
- {
- switch (code2)
- {
- case XAException.XA_HEURMIX:
- code1 = XAException.XA_HEURMIX;
- break;
- case XAException.XA_HEURRB:
- if (code1 == HEUR_NONE)
- code1 = XAException.XA_HEURRB;
- else if (code1 == XAException.XA_HEURCOM ||
- code1 == XAException.XA_HEURHAZ)
- code1 = XAException.XA_HEURMIX;
- break;
- case XAException.XA_HEURCOM:
- if (code1 == HEUR_NONE)
- code1 = XAException.XA_HEURCOM;
- else if (code1 == XAException.XA_HEURRB ||
- code1 == XAException.XA_HEURHAZ)
- code1 = XAException.XA_HEURMIX;
- break;
- case XAException.XA_HEURHAZ:
- if (code1 == HEUR_NONE)
- code1 = XAException.XA_HEURHAZ;
- else if (code1 == XAException.XA_HEURCOM ||
- code1 == XAException.XA_HEURRB)
- code1 = XAException.XA_HEURMIX;
- break;
- default:
- throw new IllegalArgumentException();
- }
-
- return code1;
- }
-
- /**
- * We got another heuristic.
- * <p/>
- * Promote <code>heuristicCode</code> if needed and remember to call forget
- * on the resource at a later time, upon request from the coordinator
- * or from a management application.
- *
- * This will release the lock while calling out.
- *
- * @param resource the resource of the XA resource that got a
- * heuristic in our internal tables, or <code>null</code>
- * if the heuristic came from here.
- * @param code the heuristic code, one of
- * <code>XAException.XA_HEURxxx</code>.
- */
- private void gotHeuristic(EnlistedResource resource, int code)
- {
- heuristicCode = groupHeuristics(heuristicCode, code);
- if (resource != null)
- resource.remember(code);
- }
-
- /**
- * Checks if a mixed decision happened and promote the
- * <code>heuristicCode</code> in that case.
- *
- * @return the <code>heuristicCode</code>.
- */
- private int consolidateHeuristics()
- {
- if (committedResources > 0 && rolledbackResources > 0)
- heuristicCode = XAException.XA_HEURMIX;
-
- return heuristicCode;
- }
-
- /**
- * Gets the full heuristic code, which includes an heuristic hazard if this
- * <code>TransactionImpl</code> could not reach a resource during the second
- * phase of 2PC.
- *
- * @return the full heuristic code, one of
- * <code>XAException.XA_HEURxxx</code>.
- */
- private int getFullHeuristicCode()
- {
- return (heuristicHazard) ?
- groupHeuristics(heuristicCode, XAException.XA_HEURHAZ) :
- heuristicCode;
- }
-
- /**
- * Check for heuristics and throw exception if any found.
- */
- private void checkHeuristics()
- throws HeuristicHazardException,
- HeuristicMixedException,
- HeuristicRollbackException
- {
- if (committedResources > 0 && rolledbackResources > 0)
- heuristicCode = XAException.XA_HEURMIX;
-
- switch (getFullHeuristicCode())
- {
- case XAException.XA_HEURHAZ:
- if (trace)
- log.trace("Throwing HeuristicHazardException, tx=" + toString() +
- ", status=" + TxUtils.getStatusAsString(status));
- throw new HeuristicHazardException();
- case XAException.XA_HEURMIX:
- if (trace)
- log.trace("Throwing HeuristicMixedException, tx=" + toString() +
- ", status=" + TxUtils.getStatusAsString(status));
- throw new HeuristicMixedException();
- case XAException.XA_HEURRB:
- if (trace)
- log.trace("Throwing HeuristicRollbackException, tx=" + toString() +
- ", status=" + TxUtils.getStatusAsString(status));
- throw new HeuristicRollbackException();
- case XAException.XA_HEURCOM:
- // Why isn't HeuristicCommitException used in JTA ?
- // And why define something that is not used ?
- if (trace)
- log.trace("NOT Throwing HeuristicCommitException, tx=" + toString()
- + ", status=" + TxUtils.getStatusAsString(status));
- return;
- }
- }
-
- private void checkHeuristicsButDoNotThrowHeuristicHazard()
- throws HeuristicMixedException,
- HeuristicRollbackException
- {
- if (committedResources > 0 && rolledbackResources > 0)
- heuristicCode = XAException.XA_HEURMIX;
-
- switch (getFullHeuristicCode())
- {
- case XAException.XA_HEURHAZ:
- if (TxManager.getInstance().isReportHeuristicHazardAsHeuristicMixed())
- {
- if (trace)
- log.trace("Throwing HeuristicMixedException instead of " +
- "HeuristicHazardException, tx=" + toString() +
- ", status=" + TxUtils.getStatusAsString(status));
- throw new HeuristicMixedException();
- }
- else
- {
- if (trace)
- log.trace("NOT throwing HeuristicHazardException, tx=" +
- toString() + ", status=" +
- TxUtils.getStatusAsString(status));
- return;
- }
- case XAException.XA_HEURMIX:
- if (trace)
- log.trace("Throwing HeuristicMixedException, tx=" + toString() +
- ", status=" + TxUtils.getStatusAsString(status));
- throw new HeuristicMixedException();
- case XAException.XA_HEURRB:
- if (trace)
- log.trace("Throwing HeuristicRollbackException, tx=" + toString() +
- ", status=" + TxUtils.getStatusAsString(status));
- throw new HeuristicRollbackException();
- case XAException.XA_HEURCOM:
- // Why isn't HeuristicCommitException used in JTA ?
- // And why define something that is not used ?
- if (trace)
- log.trace("NOT Throwing HeuristicCommitException, tx=" + toString()
- + ", status=" + TxUtils.getStatusAsString(status));
- return;
- }
- }
-
- /**
- * Registers this transaction as a resource with its parent coordinator.
- * Called from <code>enlistResource</code>.
- *
- * @throws RollbackException
- * @throws java.lang.IllegalStateException
- *
- * @throws SystemException
- */
- private void registerResourceWithParentCoordinator()
- throws RollbackException
- {
- if (trace)
- log.trace("registerResourceWithParentCoordinator(): Entered, tx=" +
- toString() + ", status=" + TxUtils.getStatusAsString(status));
-
- Resource r = null;
-
- if (Proxy.isProxyClass(parentCoordinator.getClass()))
- {
- // DTM coordinator case
- if (dtmResourceFactory != null)
- r = dtmResourceFactory.createResource(getLocalIdValue());
- else
- {
- log.warn("Missing DTM resource factory, tx=" + toString());
- status = Status.STATUS_MARKED_ROLLBACK;
- throw new RollbackException("Missing DTM resource factory");
- }
- }
- else
- {
- // OTS coordinator case
- if (otsResourceFactory != null)
- r = otsResourceFactory.createResource(getLocalIdValue());
- else
- {
- log.warn("Missing OTS resource factory, tx=" + toString());
- status = Status.STATUS_MARKED_ROLLBACK;
- throw new RollbackException("Missing OTS resource factory");
- }
- }
-
- try
- {
- unlock();
- try
- {
- recoveryCoordinator = parentCoordinator.registerResource(r);
- registeredResource = r;
- }
- finally
- {
- lock();
- }
- }
- catch (TransactionInactiveException e)
- {
- status = Status.STATUS_MARKED_ROLLBACK;
- if (trace)
- log.trace("Got TransactionInactiveException, " +
- "throwing RollbackException");
- throw new RollbackException(e.toString());
- }
- catch (TransactionRolledbackException e)
- {
- status = Status.STATUS_MARKED_ROLLBACK;
- if (trace)
- log.trace("Got TransactionRolledbackException, " +
- "throwing RollbackException");
- throw new RollbackException(e.toString());
- }
- catch (RemoteException e)
- {
- status = Status.STATUS_MARKED_ROLLBACK;
- if (trace)
- log.trace("Got RemoteException, throwing RollbackException");
- throw new RollbackException(e.toString());
- }
- }
-
- /**
- * Prepare all enlisted resources.
- * If the first phase of the commit process results in a decision
- * to commit the <code>status</code> will be
- * <code>Status.STATUS_PREPARED</code> on return.
- * Otherwise the <code>status</code> will be
- * <code>Status.STATUS_MARKED_ROLLBACK</code> on return.
- * This will release the lock while calling out.
- *
- * @return True iff all resources voted read-only.
- */
- private boolean prepareResources()
- {
- boolean readOnly = true;
-
- status = Status.STATUS_PREPARING;
-
- // Prepare XA resources.
-
- if (trace)
- log.trace("Preparing " + xaResources.size() + " XA resource(s)");
-
- for (int i = 0; i < xaResources.size(); ++i)
- {
- // Abort prepare on state change.
- if (status != Status.STATUS_PREPARING)
- return false;
-
- EnlistedXAResource resource = (EnlistedXAResource) xaResources.get(i);
-
- if (resource.isResourceManager() == false)
- continue; // This RM already prepared.
-
- // Ignore the last resource it is done later
- if (resource == lastResource)
- continue;
-
- try
- {
- int vote = resource.prepare();
-
- if (trace)
- {
- String strVote =
- (vote == RS_VOTE_OK) ?
- "OK" :
- ((vote == RS_VOTE_READONLY) ? "READONLY" : "ROLLBACK");
-
- log.trace("XA resource voted " + strVote);
- }
-
- if (vote == RS_VOTE_OK)
- readOnly = false;
- else if (vote != RS_VOTE_READONLY)
- {
- // Neither commit vote nor readonly vote: rollback.
- if (trace)
- log.trace("prepareResources got a rollback vote " +
- "from an XA resource, tx=" + toString() +
- " resource=" + resource, new Exception());
- status = Status.STATUS_MARKED_ROLLBACK;
- return false;
- }
- }
- catch (XAException e)
- {
- readOnly = false;
- logXAException(e);
- switch (e.errorCode)
- {
- case XAException.XA_HEURCOM:
- // Heuristic commit is not that bad when preparing.
- // But it means trouble if we have to rollback.
- gotHeuristic(resource, e.errorCode);
- break;
- case XAException.XA_HEURRB:
- case XAException.XA_HEURMIX:
- case XAException.XA_HEURHAZ:
- // Other heuristic exceptions cause a rollback
- gotHeuristic(resource, e.errorCode);
- // fall through
- default:
- cause = e;
- status = Status.STATUS_MARKED_ROLLBACK;
- break;
- }
- }
- catch (Throwable t)
- {
- if (t instanceof RecoveryTestingException)
- throw (RecoveryTestingException)t;
-
- if (trace)
- log.trace("unhandled throwable in prepareResources " +
- toString(), t);
- status = Status.STATUS_MARKED_ROLLBACK;
- cause = t;
- return false;
- }
- }
-
- // Prepare remote DTM/OTS resources.
-
- if (trace)
- log.trace("Preparing " + remoteResources.size() +
- " remote resource(s)");
-
- for (int i = 0; i < remoteResources.size(); ++i)
- {
- // Abort prepare on state change.
- if (status != Status.STATUS_PREPARING)
- return false;
-
- EnlistedRemoteResource resource =
- (EnlistedRemoteResource) remoteResources.get(i);
-
- try
- {
- int vote = resource.prepare();
-
- if (trace)
- {
- String strVote =
- (vote == RS_VOTE_OK) ?
- "OK" :
- ((vote == RS_VOTE_READONLY) ? "READONLY" : "ROLLBACK");
-
- log.trace("Remote resource voted " + strVote);
- }
-
- if (vote == RS_VOTE_OK)
- readOnly = false;
- else if (vote != RS_VOTE_READONLY)
- {
- // Neither commit vote nor readonly vote: rollback.
- if (trace)
- log.trace("prepareResources got a rollback vote " +
- "from a remote resource, tx=" + toString() +
- ", resource=" + resource, new Exception());
- status = Status.STATUS_MARKED_ROLLBACK;
- return false;
- }
- }
- catch (Exception e)
- {
- // Blanket catch for the following exception types:
- // TransactionAlreadyPreparedException,
- // HeuristicMixedException,
- // HeuristicHazardException, and
- // RemoteException, which includes TransactionRolledbackException.
- if (trace)
- log.trace("Exception in prepareResources, tx=" + toString(), e);
-
- if (e instanceof HeuristicMixedException)
- gotHeuristic(resource, XAException.XA_HEURMIX);
- else if (e instanceof HeuristicHazardException)
- gotHeuristic(resource, XAException.XA_HEURHAZ);
-
- cause = e;
- status = Status.STATUS_MARKED_ROLLBACK;
- }
- }
-
- // Abort prepare on state change.
- if (status != Status.STATUS_PREPARING)
- return false;
-
- // Are we doing the last resource gambit?
- if (lastResource != null)
- {
- try
- {
- lastResource.prepareLastResource();
- lastResource.commit(false);
- }
- catch (XAException e)
- {
- if (trace)
- log.trace("prepareResources got XAException" +
- " when committing last resource, tx=" + toString(), e);
- logXAException(e);
- switch (e.errorCode)
- {
- // No need to handle the case of XAException.XA_HEURCOM,
- // which is swallowed by EnlistedXAResource.commit()
- case XAException.XA_HEURRB:
- case XAException.XA_HEURMIX:
- case XAException.XA_HEURHAZ:
- //usually throws an exception, but not for a couple of cases.
- gotHeuristic(lastResource, e.errorCode);
- // fall through
- default:
- // take the XAException as a "no" vote from the last resource
- status = Status.STATUS_MARKED_ROLLBACK;
- cause = e;
- return false; // to make the caller look at
- // at the "marked rollback" status
- }
- }
- catch (Throwable t)
- {
- if (trace)
- log.trace("unhandled throwable in prepareResources, tx=" +
- toString(), t);
- status = Status.STATUS_MARKED_ROLLBACK;
- cause = t;
- return false; // to make the caller look at
- // the "marked rollback" status
- }
- }
-
- if (status == Status.STATUS_PREPARING)
- status = Status.STATUS_PREPARED;
- else
- return false;
-
- return readOnly;
- }
-
- /**
- * Commit all enlisted resources.
- * This will release the lock while calling out.
- */
- private void commitResources(boolean onePhase)
- {
- status = Status.STATUS_COMMITTING;
- doCommitResources(onePhase);
- if (xaResourcesToRetry > 0 || remoteResourcesToRetry > 0)
- {
- int retryLimit = TxManager.getInstance().getCompletionRetryLimit();
- for (int n = 0;
- n < retryLimit &&
- (xaResourcesToRetry > 0 || remoteResourcesToRetry > 0);
- n++)
- {
- sleep(TxManager.getInstance().getCompletionRetryTimeoutMillis());
- doCommitResources(onePhase);
- }
- }
- checkCommitCompletion();
- }
-
- /**
- * Do the actual resource commiting.
- */
- private void doCommitResources(boolean onePhase)
- {
- xaResourcesToRetry = 0;
- remoteResourcesToRetry = 0;
-
- // Commit XA resources.
- for (int i = 0; i < xaResources.size(); ++i)
- {
-
- // Abort commit on state change.
- if (status != Status.STATUS_COMMITTING)
- return;
-
- EnlistedXAResource resource =
- (EnlistedXAResource) xaResources.get(i);
-
- // Ignore the last resource, it is already committed
- if (onePhase == false && lastResource == resource)
- continue;
-
- try
- {
- resource.commit(onePhase);
- }
- catch (XAException e)
- {
- logXAException(e);
- switch (e.errorCode)
- {
- // No need to handle the case of XAException.XA_HEURCOM,
- // which is swallowed by EnlistedXAResource.commit()
- case XAException.XA_HEURRB:
- case XAException.XA_HEURMIX:
- case XAException.XA_HEURHAZ:
- //usually throws an exception, but not for a couple of cases.
- gotHeuristic(resource, e.errorCode);
- if (onePhase)
- status = Status.STATUS_MARKED_ROLLBACK;
- break;
- case XAException.XAER_RMERR:
- // Not much we can do if there is an RMERR in the
- // commit phase of 2pc. I guess we take it as a heuristic
- // rollback and try the other RMs.
- gotHeuristic(null, XAException.XA_HEURRB);
- if (onePhase)
- status = Status.STATUS_MARKED_ROLLBACK;
- break;
- case XAException.XAER_RMFAIL:
- case XAException.XA_RETRY:
- if (onePhase)
- status = Status.STATUS_MARKED_ROLLBACK;
- else
- // The XAResource remains prepared. Retry the commit later.
- xaResourcesToRetry++;
- break;
- case XAException.XAER_NOTA:
- case XAException.XAER_INVAL:
- case XAException.XAER_PROTO:
- default:
- // This should never happen!
- cause = e;
- if (onePhase)
- status = Status.STATUS_MARKED_ROLLBACK;
- else
- log.warn("Could not recover from unexpected XAException: " +
- "tx=" + toString() + " errorCode=" +
- TxUtils.getXAErrorCodeAsString(e.errorCode), e);
- break;
- }
- }
- catch (Throwable t)
- {
- if (t instanceof RecoveryTestingException)
- throw (RecoveryTestingException) t;
- if (trace)
- log.trace("Unhandled throwable in doCommitResources " +
- toString(), t);
- }
- }
-
- // Commit remote DTM/OTS resources.
- for (int i = 0; i < remoteResources.size(); ++i)
- {
- // Abort commit on state change.
- if (status != Status.STATUS_COMMITTING)
- return;
-
- EnlistedRemoteResource resource =
- (EnlistedRemoteResource) remoteResources.get(i);
-
- try
- {
- resource.commit(onePhase);
- }
- catch (TransactionRolledbackException e)
- {
- if (trace)
- log.trace("Exception in doCommitResources, tx=" + toString(), e);
-
- if (onePhase)
- status = Status.STATUS_MARKED_ROLLBACK;
- else
- {
- // The resource decided to rollback in the second phase of 2PC:
- // this is a heuristic outcome.
- gotHeuristic(null, XAException.XA_HEURRB);
- }
- }
- catch (HeuristicRollbackException e)
- {
- if (trace)
- log.trace("Exception in doCommitResources, tx=" + toString(), e);
-
- gotHeuristic(resource, XAException.XA_HEURRB);
- if (onePhase)
- status = Status.STATUS_MARKED_ROLLBACK;
- }
- catch (HeuristicMixedException e)
- {
- if (trace)
- log.trace("Exception in doCommitResources, tx=" + toString(), e);
-
- gotHeuristic(resource, XAException.XA_HEURMIX);
- if (onePhase)
- status = Status.STATUS_MARKED_ROLLBACK;
- }
- catch (HeuristicHazardException e)
- {
- if (trace)
- log.trace("Exception in doCommitResources, tx=" + toString(), e);
-
- gotHeuristic(resource, XAException.XA_HEURHAZ);
- if (onePhase)
- status = Status.STATUS_MARKED_ROLLBACK;
- }
- catch (TransactionNotPreparedException e)
- {
- // This should never happen!
- cause = e;
- if (trace)
- log.trace("Exception in doCommitResources, tx=" + toString(), e);
- if (onePhase)
- status = Status.STATUS_MARKED_ROLLBACK;
- else
- log.warn("Could not recover from unexpected exception in " +
- "doCommitResources: tx=" + toString() +
- " exception=" + e);
- }
- catch (NoSuchObjectException e)
- {
- if (trace)
- log.trace("Exception in doCommitResources, tx=" + toString(), e);
- if (onePhase)
- status = Status.STATUS_MARKED_ROLLBACK;
- else
- {
- // Do nothing -- we must be doing crash recovery and the
- // remote resource has been committed before the crash.
- log.warn("Ignoring NoSuchObjectException in doCommitResources: "
- + " tx=" + toString() + " exception=" + e);
- }
- }
- catch (RemoteException e)
- {
- if (trace)
- log.trace("Exception in doCommitResources, tx=" + toString(), e);
- if (onePhase)
- status = Status.STATUS_MARKED_ROLLBACK;
- else
- {
- // The remote resource remains prepared. Retry the commit later.
- remoteResourcesToRetry++;
- }
- }
- }
- }
-
- /**
- * Create retry timeout for calling retryCommitXAResources().
- */
- private void commitXAResourcesAfterTimeout()
- {
- xaRetryTimeout = timeoutFactory.createTimeout(
- System.currentTimeMillis() +
- TxManager.getInstance().getXARetryTimeoutMillis(),
- new TimeoutTarget()
- {
- public void timedOut(Timeout timeout)
- {
- if (trace)
- log.trace("XA retry timeout expired for tx=" +
- TransactionImpl.this.toString() +
- ", retrying commit on XAResources");
- lock();
- try
- {
- retryCommitXAResources();
- if (xaResourcesToRetry > 0)
- {
- xaRetryTimeout = timeoutFactory.createTimeout(
- System.currentTimeMillis() +
- TxManager.getInstance().getXARetryTimeoutMillis(),
- this);
- }
- else if (remoteResourcesToRetry == 0 &&
- heuristicCode == HEUR_NONE)
- {
- completeTransaction();
- }
- }
- finally
- {
- unlock();
- }
- }
- });
- }
-
- // Pre-condition: this TransactionImpl instance is locked.
- // Post-condition: this TransactionImpl instance remains locked.
- private void retryCommitXAResources()
- {
- if (trace)
- log.trace("Retrying commit XA resources, tx=" + toString() +
- ", status=" + TxUtils.getStatusAsString(status) +
- ", xaResourcesToRetry=" + xaResourcesToRetry);
-
- xaResourcesToRetry = 0;
-
- for (int i = 0; i < xaResources.size(); ++i)
- {
- EnlistedXAResource resource =
- (EnlistedXAResource) xaResources.get(i);
-
- // Ignore the last resource, it is already committed
- if (lastResource == resource)
- continue;
-
- try
- {
- resource.commit(false);
- }
- catch (XAException e)
- {
- logXAException(e);
- switch (e.errorCode)
- {
- // No need to handle the case of XAException.XA_HEURCOM,
- // which is swallowed by EnlistedXAResource.commit()
- case XAException.XA_HEURRB:
- case XAException.XA_HEURMIX:
- case XAException.XA_HEURHAZ:
- //usually throws an exception, but not for a couple of cases.
- gotHeuristic(resource, e.errorCode);
- break;
- case XAException.XAER_RMERR:
- // Not much we can do if there is an RMERR in the
- // commit phase of 2pc. I guess we take it as a heuristic
- // rollback and try the other RMs.
- gotHeuristic(null, XAException.XA_HEURRB);
- break;
- case XAException.XAER_RMFAIL:
- case XAException.XA_RETRY:
- // The XAResource remains prepared. Retry the commit later.
- xaResourcesToRetry++;
- break;
- case XAException.XAER_NOTA:
- case XAException.XAER_INVAL:
- case XAException.XAER_PROTO:
- default:
- // This should never happen!
- log.warn("Could not recover from unexpected XAException: " +
- "tx=" + toString() + " errorCode=" +
- TxUtils.getXAErrorCodeAsString(e.errorCode), e);
- break;
- }
- }
- catch (Throwable t)
- {
- if (t instanceof RecoveryTestingException)
- throw (RecoveryTestingException) t;
- if (trace)
- log.trace("unhandled throwable in retryCommitXAResources " +
- this, t);
- }
- }
-
- if (trace)
- log.trace("Finished retrying commit XA resources, tx=" + toString() +
- ", status=" + TxUtils.getStatusAsString(status) +
- ", xaResourcesToRetry=" + xaResourcesToRetry);
-
- checkCommitCompletion();
- }
-
- // Pre-condition: this TransactionImpl instance is locked.
- // Post-condition: this TransactionImpl instance remains locked.
- private void retryCommitRemoteResources()
- {
- if (trace)
- log.trace("Retrying commit remote resources, tx=" + toString() +
- ", status=" + TxUtils.getStatusAsString(status) +
- ", " + remoteResources.size() + " remote resources");
-
- remoteResourcesToRetry = 0;
-
- // Commit remote DTM/OTS resources.
- for (int i = 0; i < remoteResources.size(); ++i)
- {
- EnlistedRemoteResource resource =
- (EnlistedRemoteResource) remoteResources.get(i);
-
- try
- {
- resource.commit(false);
- }
- catch (HeuristicRollbackException e)
- {
- if (trace)
- log.trace("Exception in retryCommitRemoteResources, tx=" +
- toString(), e);
-
- gotHeuristic(resource, XAException.XA_HEURRB);
- }
- catch (HeuristicMixedException e)
- {
- if (trace)
- log.trace("Exception in retryCommitRemoteResources, tx=" +
- toString(), e);
-
- gotHeuristic(resource, XAException.XA_HEURMIX);
- }
- catch (HeuristicHazardException e)
- {
- if (trace)
- log.trace("Exception in retryCommitRemoteResources, tx=" +
- toString(), e);
-
- gotHeuristic(resource, XAException.XA_HEURHAZ);
- }
- catch (TransactionNotPreparedException e)
- {
- // This should never happen!
- cause = e;
- if (trace)
- log.trace("Exception in retryCommitRemoteResources, tx=" +
- toString(), e);
- log.warn("Could not recover from unexpected exception in " +
- "retryCommitRemoteResources: tx=" + toString() +
- " exception=" + e);
- }
- catch (NoSuchObjectException e)
- {
- if (trace)
- log.trace("Exception in retryCommitRemoteResources, tx=" +
- toString(), e);
-
- // Do nothing -- we must be doing crash recovery and the
- // remote resource has been committed before the crash.
- log.warn("Ignoring NoSuchObjectException in " +
- "retryCommitRemoteResources: tx=" + toString() +
- " exception=" + e);
- }
- catch (RemoteException e)
- {
- if (trace)
- log.trace("Exception in retryCommitRemoteResources, tx=" +
- toString(), e);
-
- // The remote resource remains prepared. Retry the commit later.
- remoteResourcesToRetry++;
- }
- }
-
- if (trace)
- log.trace("Finished retrying commit remote resources, tx=" + toString()
- + ", status=" + TxUtils.getStatusAsString(status) +
- ", remoteResourcesToRetry=" + remoteResourcesToRetry +
- " of " + remoteResources.size() + " remote resources");
-
- checkCommitCompletion();
- }
-
- private void checkCommitCompletion()
- {
- if (status != Status.STATUS_COMMITTING)
- return;
-
- consolidateHeuristics();
-
- if (xaResourcesToRetry == 0 && remoteResourcesToRetry == 0)
- {
- status = Status.STATUS_COMMITTED;
- if (heuristicHazard || heuristicCode != HEUR_NONE)
- {
- heuristicHazard = false;
-
- // Save the heuristic status to stable storage. Do not include
- // a locally-detected heuristic hazard, as the actual heuristic
- // outcome is known at this point.
- RecoveryLogger logger = TxManager.getInstance().getRecoveryLogger();
- if (logger != null)
- logger.saveHeuristicStatus(xid.getLocalIdValue(),
- foreignTx,
- xid.getFormatId(),
- xid.getGlobalTransactionId(),
- inboundBranchQualifier,
- status,
- heuristicCode,
- heuristicHazard,
- getXAResourceHeuristics(),
- getRemoteResourceHeuristics());
- if (!foreignTx &&
- !TxManager.getInstance().isRootBranchRemembersHeuristicDecisions() &&
- forgetResources())
- {
- // Clear heuristic status
- if (logger != null)
- {
- long localId = xid.getLocalIdValue();
- logger.clearHeuristicStatus(localId);
- if (completionHandler != null)
- completionHandler.handleTxCompletion(localId);
- }
- }
- }
- else if (completionHandler != null)
- completionHandler.handleTxCompletion(xid.getLocalIdValue());
- }
- else if (!heuristicHazard)
- {
- heuristicHazard = true;
-
- // Save the heuristic status to stable storage, including the
- // locally-detected heuristic hazard.
- RecoveryLogger logger = TxManager.getInstance().getRecoveryLogger();
- if (logger != null)
- logger.saveHeuristicStatus(xid.getLocalIdValue(),
- foreignTx,
- xid.getFormatId(),
- xid.getGlobalTransactionId(),
- inboundBranchQualifier,
- status,
- heuristicCode,
- heuristicHazard,
- getXAResourceHeuristics(),
- getRemoteResourceHeuristics());
-
- if (!foreignTx &&
- !TxManager.getInstance().isRootBranchRemembersHeuristicDecisions())
- forgetResources();
- }
- }
-
- /**
- * Rollback all enlisted resources and complete the transaction.
- * This will release the lock while calling out.
- */
- private void rollbackResourcesAndCompleteTransaction()
- {
- status = Status.STATUS_ROLLING_BACK;
- doRollbackResources();
- if (xaResourcesToRetry > 0 || remoteResourcesToRetry > 0)
- {
- int retryLimit = TxManager.getInstance().getCompletionRetryLimit();
- for (int n = 0;
- n < retryLimit &&
- (xaResourcesToRetry > 0 || remoteResourcesToRetry > 0);
- n++)
- {
- sleep(TxManager.getInstance().getCompletionRetryTimeoutMillis());
- doRollbackResources();
- }
- }
-
- if (xaResourcesToRetry == 0 && remoteResourcesToRetry == 0)
- {
- status = Status.STATUS_ROLLEDBACK;
-
- if (consolidateHeuristics() != HEUR_NONE || heuristicHazard)
- {
- heuristicHazard = false;
-
- // Save the heuristic status to stable storage. Do not include
- // a locally-generated heuristic hazard, as the actual heuristic
- // outcome is known at this point.
- RecoveryLogger logger = TxManager.getInstance().getRecoveryLogger();
- if (logger != null)
- logger.saveHeuristicStatus(xid.getLocalIdValue(),
- foreignTx,
- xid.getFormatId(),
- xid.getGlobalTransactionId(),
- inboundBranchQualifier,
- status,
- heuristicCode,
- heuristicHazard,
- getXAResourceHeuristics(),
- getRemoteResourceHeuristics());
- if (!foreignTx &&
- !TxManager.getInstance().isRootBranchRemembersHeuristicDecisions() &&
- forgetResources())
- {
- // Clear heuristic status
- if (logger != null)
- {
- long localId = xid.getLocalIdValue();
- logger.clearHeuristicStatus(localId);
- }
- }
- }
- else
- completeTransaction();
- }
- else
- {
- if (!heuristicHazard)
- {
- heuristicHazard = true;
- consolidateHeuristics();
-
- // Save the heuristic status to stable storage, including the
- // locally-detected heuristic hazard.
- RecoveryLogger logger = TxManager.getInstance().getRecoveryLogger();
- if (logger != null)
- logger.saveHeuristicStatus(xid.getLocalIdValue(),
- foreignTx,
- xid.getFormatId(),
- xid.getGlobalTransactionId(),
- inboundBranchQualifier,
- status,
- heuristicCode,
- heuristicHazard,
- getXAResourceHeuristics(),
- getRemoteResourceHeuristics());
- }
- if (xaResourcesToRetry > 0)
- rollbackXAResourcesAfterTimeout();
- }
- }
-
- /**
- * Do the actual resource rolling back.
- */
- private void doRollbackResources()
- {
- xaResourcesToRetry = 0;
- remoteResourcesToRetry = 0;
-
- // Rollback XA resources.
- for (int i = 0; i < xaResources.size(); ++i)
- {
- EnlistedXAResource resource = (EnlistedXAResource) xaResources.get(i);
- try
- {
- resource.rollback();
- }
- catch (XAException e)
- {
- logXAException(e);
- switch (e.errorCode)
- {
- // No need to handle the case of XAException.XA_HEURRB,
- // which is swallowed by EnlistedXAResource.rollback()
- case XAException.XA_HEURCOM:
- case XAException.XA_HEURMIX:
- case XAException.XA_HEURHAZ:
- gotHeuristic(resource, e.errorCode);
- continue;
- default:
- cause = e;
- break;
- }
- }
- catch (Throwable t)
- {
- if (t instanceof RecoveryTestingException)
- throw (RecoveryTestingException) t;
- if (trace)
- log.trace("unhandled throwable in doRollbackResources " + this,
- t);
- }
- if (resource.getState() == RS_VOTE_OK)
- xaResourcesToRetry++;
- }
-
- // Rollback remote DTM/OTS resources.
- for (int i = 0; i < remoteResources.size(); ++i)
- {
- EnlistedRemoteResource resource =
- (EnlistedRemoteResource) remoteResources.get(i);
-
- try
- {
- resource.rollback();
- }
- catch (HeuristicCommitException e)
- {
- gotHeuristic(resource, XAException.XA_HEURCOM);
- continue;
- }
- catch (HeuristicMixedException e)
- {
- gotHeuristic(resource, XAException.XA_HEURMIX);
- continue;
- }
- catch (HeuristicHazardException e)
- {
- gotHeuristic(resource, XAException.XA_HEURHAZ);
- continue;
- }
- catch (RemoteException e)
- {
- // No need to do much here. If the resource didn't get the
- // rollback then it will eventually call replay completion on
- // the recovery coordinator. We increase remoteResourcesToRetry
- // for heuristic hazard reporting purposes only.
- remoteResourcesToRetry++;
- if (trace)
- log.trace("Ignoring exception in remote resource rollback, tx=" +
- toString(), e);
- }
- }
- }
-
- /**
- * Create timeout for calling retryRollbackXAResources().
- */
- private void rollbackXAResourcesAfterTimeout()
- {
- xaRetryTimeout = timeoutFactory.createTimeout(
- System.currentTimeMillis() +
- TxManager.getInstance().getXARetryTimeoutMillis(),
- new TimeoutTarget()
- {
- public void timedOut(Timeout timeout)
- {
- if (trace)
- log.trace("XA retry timeout expired for tx=" +
- TransactionImpl.this.toString() +
- ", retrying rollback on XAResources");
- lock();
- try
- {
- retryRollbackXAResources();
- if (xaResourcesToRetry > 0)
- {
- xaRetryTimeout = timeoutFactory.createTimeout(
- System.currentTimeMillis() +
- TxManager.getInstance().getXARetryTimeoutMillis(),
- this);
- }
- else if (remoteResourcesToRetry == 0 &&
- heuristicCode == HEUR_NONE)
- {
- completeTransaction();
- }
- }
- finally
- {
- unlock();
- }
- }
- });
- }
-
- /**
- * Cancel XA retry timeout.
- */
- private void cancelXARetryTimeout()
- {
- if (xaRetryTimeout != null)
- {
- Timeout rt = xaRetryTimeout;
- xaRetryTimeout = null;
-
- unlock();
- try
- {
- rt.cancel();
- }
- catch (Exception e)
- {
- if (trace)
- log.trace("failed to cancel XA retry timeout, tx=" + toString(),
- e);
- }
- finally
- {
- lock();
- }
- }
- }
-
- private int[] getXAResourceHeuristics()
- {
- if (xaResourcesWithHeuristicDecisions == null)
- return null;
- else
- {
- int[] heurCodes = new int[xaResourcesWithHeuristicDecisions.size()];
- for (int i = 0; i < xaResourcesWithHeuristicDecisions.size(); ++i)
- {
- EnlistedResource resource =
- (EnlistedResource) xaResourcesWithHeuristicDecisions.get(i);
- heurCodes[i] = resource.getHeuristicCode();
- }
- return heurCodes;
- }
- }
-
- private HeuristicStatus[] getRemoteResourceHeuristics()
- {
- if (remoteResourcesWithHeuristicDecisions == null)
- return null;
- else
- {
- HeuristicStatus s[] =
- new HeuristicStatus[remoteResourcesWithHeuristicDecisions.size()];
- for (int i = 0; i < remoteResourcesWithHeuristicDecisions.size(); ++i)
- {
- EnlistedRemoteResource resource =
- (EnlistedRemoteResource) remoteResourcesWithHeuristicDecisions.get(i);
- s[i] = new HeuristicStatus(
- resource.getHeuristicCode(),
- resourceToString(resource.getRemoteResource()));
- }
- return s;
- }
- }
-
-
- private void retryRollbackXAResources()
- {
- xaResourcesToRetry = 0;
-
- // Rollback XA resources.
- for (int i = 0; i < xaResources.size(); ++i)
- {
- EnlistedXAResource resource = (EnlistedXAResource) xaResources.get(i);
- try
- {
- resource.rollback();
- }
- catch (XAException e)
- {
- logXAException(e);
- switch (e.errorCode)
- {
- // No need to handle the case of XAException.XA_HEURRB,
- // which is swallowed by EnlistedXAResource.rollback()
- case XAException.XA_HEURCOM:
- case XAException.XA_HEURMIX:
- case XAException.XA_HEURHAZ:
- gotHeuristic(resource, e.errorCode);
- continue;
- default:
- cause = e;
- break;
- }
- }
- catch (Throwable t)
- {
- if (t instanceof RecoveryTestingException)
- throw (RecoveryTestingException) t;
- if (trace)
- log.trace("unhandled throwable in retryRollbackXAResources " +
- this, t);
- }
- if (resource.getState() == RS_VOTE_OK)
- xaResourcesToRetry++;
- }
-
- if (xaResourcesToRetry == 0 && remoteResourcesToRetry == 0)
- status = Status.STATUS_ROLLEDBACK;
- }
-
- private boolean forgetResources()
- {
- boolean success = true;
- if (xaResourcesWithHeuristicDecisions != null)
- {
- for (int i = 0; i < xaResourcesWithHeuristicDecisions.size(); ++i)
- {
- EnlistedResource resource =
- (EnlistedResource) xaResourcesWithHeuristicDecisions.get(i);
- resource.forget();
- if (resource.getState() != RS_FORGOT)
- success = false;
- }
- }
-
- if (remoteResourcesWithHeuristicDecisions != null)
- {
- for (int i = 0; i < remoteResourcesWithHeuristicDecisions.size(); ++i)
- {
- EnlistedResource resource =
- (EnlistedResource) remoteResourcesWithHeuristicDecisions.get(i);
- resource.forget();
- if (resource.getState() != RS_FORGOT)
- success = false;
- }
- }
- return success;
- }
-
- /**
- * Create an Xid representing a new branch of this transaction.
- */
- private Xid createXidBranch()
- {
- long branchId = ++lastBranchId;
-
- return xidFactory.newBranch(xid, branchId);
- }
-
- /**
- * Determine the commit strategy
- *
- * @return 0 for nothing to do, 1 for one phase and 2 for two phase
- */
- private int getCommitStrategy()
- {
- int xaResourceCount = xaResources.size();
- int remoteResourceCount = remoteResources.size();
- int resourceCount = xaResourceCount + remoteResourceCount;
-
- if (resourceCount == 0)
- return 0;
-
- if (resourceCount == 1)
- return 1;
-
- // At least two resources have participated in this transaction.
-
- if (remoteResourceCount > 0)
- {
- // They cannot be all XA resources on the same RM,
- // as at least one of them is a remote DTM/OTS resource.
- return 2;
- }
- else // They are all XA resources, look if the're all on the same RM.
- {
- // First XAResource surely isResourceManager, it's the first!
- for (int i = 1; i < xaResourceCount; ++i)
- {
- EnlistedXAResource resource = (EnlistedXAResource) xaResources.get(i);
- if (resource.isResourceManager())
- {
- // this one is not the same rm as previous ones,
- // there must be at least 2
- return 2;
- }
-
- }
- // All RMs are the same one, one phase commit is ok.
- return 1;
- }
- }
-
- /**
- * Gets stringfied references for all enlisted resources that voted commit.
- *
- * @return an array of stringfied <code>Resource</code> references.
- */
- private String[] getStringfiedRemoteResourcesThatVotedCommit()
- {
- List resourcesThatVotedCommit = new ArrayList(remoteResources.size());
-
- for (int i = 0; i < remoteResources.size(); ++i)
- {
- EnlistedRemoteResource enlistedRemoteResource =
- (EnlistedRemoteResource) remoteResources.get(i);
- if (enlistedRemoteResource.getState() == RS_VOTE_OK)
- {
- Resource r = enlistedRemoteResource.getRemoteResource();
- resourcesThatVotedCommit.add(resourceToString(r));
- }
- }
- return (String[]) resourcesThatVotedCommit.toArray(
- new String[resourcesThatVotedCommit.size()]);
- }
-
- /**
- * Check we have no outstanding work
- *
- * @throws IllegalStateException when there is still work
- */
- private void checkWork()
- {
- if (work != null)
- throw new IllegalStateException("Work still outstanding: " + work +
- ", tx=" + toString());
- }
-
- /**
- * Waits (blocking the caller) for the specified number of milliseconds.
- *
- * @param millis the length of time to sleep in milliseconds.
- */
- private void sleep(long millis)
- {
- try
- {
- unlock();
- Thread.sleep(millis);
- }
- catch (InterruptedException e)
- {
- // ignore
- }
- finally
- {
- lock();
- }
- }
-
- // Inner classes -------------------------------------------------
-
- /**
- * Represents a resource enlisted in the transaction.
- * The resource can be either an XA resource or a remote DTM/OTS resource.
- */
- private interface EnlistedResource
- {
- public int getState();
- public void remember(int heuristicCode);
- int getHeuristicCode();
- public void forget();
- }
-
- /**
- * Represents an XA resource enlisted in the transaction
- */
- private class EnlistedXAResource
- implements EnlistedResource
- {
- /**
- * The XAResource
- */
- private XAResource xaResource;
-
- /**
- * The state of the resources
- */
- private int resourceState;
-
- /**
- * The related XA resource from the same resource manager
- */
- private EnlistedXAResource resourceSameRM;
-
- /**
- * The Xid of this resource
- */
- private Xid resourceXid;
-
- /**
- * The heuristic status of this resource
- */
- private int heurCode;
-
- /**
- * The XAResourceAccess instance to be released after this
- * EnlistedXAResource is committed or rolled back, or null if no
- * XAResourceAccess instance needs to be released.
- */
- private XAResourceAccess xaResourceAccess = null;
-
- /**
- * Create a new resource
- */
- public EnlistedXAResource(XAResource xaResource,
- Xid resourceXid,
- EnlistedXAResource resourceSameRM)
- {
- this.xaResource = xaResource;
- this.resourceXid = resourceXid;
- this.resourceSameRM = resourceSameRM;
- resourceState = RS_NEW;
- heurCode = HEUR_NONE;
- }
-
- /**
- * Creates a prepared resource.
- * This constructor is intended to be used during recovery only.
- */
- public EnlistedXAResource(XAWork xaWork)
- {
- this.xaResource = xaWork.res;
- this.resourceXid = xaWork.xid;
- this.xaResourceAccess = xaWork.xaResourceAccess;
- this.resourceSameRM = null;
- resourceState = RS_VOTE_OK;
- heurCode = HEUR_NONE;
- }
-
- /**
- * Creates a resource in a heuristically completed state.
- * This constructor is intended to be used during recovery only.
- */
- public EnlistedXAResource(XAResource xaResource,
- Xid resourceXid,
- boolean committed)
- {
- this.xaResource = xaResource;
- this.resourceXid = resourceXid;
- this.resourceSameRM = null;
- this.resourceState = (committed) ? RS_COMMITTED: RS_ROLLEDBACK;
- heurCode = HEUR_UNKNOWN;
- }
-
- /**
- * Get the XAResource for this resource
- */
- public XAResource getXAResource()
- {
- return xaResource;
- }
-
- /**
- * Get the Xid for this resource
- */
- public Xid getXid()
- {
- return resourceXid;
- }
-
- /**
- * Gets the state of the XAResource represented by this
- * <code>EnlistedXAResource</code> instance.
- */
- public int getState()
- {
- return resourceState;
- }
-
- /**
- * Is the resource enlisted?
- */
- public boolean isEnlisted()
- {
- return resourceState == RS_ENLISTED;
- }
-
- /**
- * Is this a resource manager
- */
- public boolean isResourceManager()
- {
- return resourceSameRM == null;
- }
-
- /**
- * Is this the resource manager for the passed XA resource
- */
- public boolean isResourceManager(XAResource xaRes)
- throws XAException
- {
- return resourceSameRM == null && xaRes.isSameRM(xaResource);
- }
-
- /**
- * Is the resource delisted and the XAResource always returns false
- * for isSameRM
- */
- public boolean isDelisted(XAResource xaRes)
- throws XAException
- {
- return resourceState == RS_ENDED && xaResource.isSameRM(xaRes) == false;
- }
-
- /**
- * Call <code>start()</code> on a XAResource and update
- * internal state information.
- * This will release the lock while calling out.
- *
- * @return true when started, false otherwise
- */
- public boolean startResource()
- throws XAException
- {
- int flags = XAResource.TMJOIN;
-
- if (resourceSameRM == null)
- {
- switch (resourceState)
- {
- case RS_NEW:
- flags = XAResource.TMNOFLAGS;
- break;
- case RS_SUSPENDED:
- flags = XAResource.TMRESUME;
- break;
-
- default:
- if (trace)
- log.trace("Unhandled resource state: " + resourceState +
- " (not RS_NEW or RS_SUSPENDED, using TMJOIN flags)");
- }
- }
-
- if (trace)
- log.trace("startResource(" +
- xidFactory.toString(resourceXid) +
- ") entered: " + xaResource.toString() +
- " flags=" + flags);
-
- unlock();
- // OSH FIXME: resourceState could be incorrect during this callout.
- try
- {
- try
- {
- xaResource.start(resourceXid, flags);
- }
- catch (XAException e)
- {
- throw e;
- }
- catch (Throwable t)
- {
- if (trace)
- log.trace("unhandled throwable error in startResource",
- t);
- status = Status.STATUS_MARKED_ROLLBACK;
- return false;
- }
-
- // Now the XA resource is associated with a transaction.
- resourceState = RS_ENLISTED;
- }
- finally
- {
- lock();
- if (trace)
- log.trace("startResource(" +
- xidFactory.toString(resourceXid) +
- ") leaving: " + xaResource.toString() +
- " flags=" + flags);
- }
- return true;
- }
-
- /**
- * Delist the resource unless we already did it
- */
- public boolean delistResource(XAResource xaRes, int flag)
- throws XAException
- {
- if (isDelisted(xaRes))
- {
- // This RM always returns false on isSameRM. Further,
- // the last resource has already been delisted.
- log.warn("Resource already delisted. tx=" +
- TransactionImpl.this.toString());
- return false;
- }
- endResource(flag);
- return true;
- }
-
- /**
- * End the resource
- */
- public void endResource()
- throws XAException
- {
- if (resourceState == RS_ENLISTED || resourceState == RS_SUSPENDED)
- {
- if (trace)
- log.trace("endresources(" + xaResource + "): state=" +
- resourceState);
- endResource(XAResource.TMSUCCESS);
- }
- }
-
- /**
- * Call <code>end()</code> on the XAResource and update
- * internal state information.
- * This will release the lock while calling out.
- *
- * @param flag The flag argument for the end() call.
- */
- private void endResource(int flag)
- throws XAException
- {
- if (trace)
- log.trace("endResource(" +
- xidFactory.toString(resourceXid) +
- ") entered: " + xaResource.toString() +
- " flag=" + flag);
-
- unlock();
- // OSH FIXME: resourceState could be incorrect during this callout.
- try
- {
- try
- {
- xaResource.end(resourceXid, flag);
- }
- catch (XAException e)
- {
- throw e;
- }
- catch (Throwable t)
- {
- if (trace)
- log.trace("unhandled throwable error in endResource", t);
- status = Status.STATUS_MARKED_ROLLBACK;
- // Resource may or may not be ended after illegal exception.
- // We just assume it ended.
- resourceState = RS_ENDED;
- return;
- }
-
- // Update our internal state information
- if (flag == XAResource.TMSUSPEND)
- resourceState = RS_SUSPENDED;
- else
- {
- if (flag == XAResource.TMFAIL)
- status = Status.STATUS_MARKED_ROLLBACK;
- resourceState = RS_ENDED;
- }
- }
- finally
- {
- lock();
- if (trace)
- log.trace("endResource(" +
- xidFactory.toString(resourceXid) +
- ") leaving: " + xaResource.toString() +
- " flag=" + flag);
- }
- }
-
- /**
- * Remember that this resource has a heuristic outcome.
- */
- public void remember(int heuristicCode)
- {
- heurCode = heuristicCode;
- if (xaResourcesWithHeuristicDecisions == null)
- xaResourcesWithHeuristicDecisions = new ArrayList();
- xaResourcesWithHeuristicDecisions.add(this);
- }
-
- /**
- * Get the heuristic status of this resource.
- */
- public int getHeuristicCode()
- {
- return heurCode;
- }
-
- /**
- * Forget the resource
- */
- public void forget()
- {
- unlock();
- if (trace)
- log.trace("Forget: " + xaResource +
- " xid=" + xidFactory.toString(resourceXid));
- try
- {
- xaResource.forget(resourceXid);
- resourceState = RS_FORGOT;
- }
- catch (XAException xae)
- {
- logXAException(xae);
- cause = xae;
- if (xae.errorCode == XAException.XAER_NOTA)
- {
- if (trace)
- log.trace("XAER_NOTA in forget: " + xaResource +
- " xid=" + xidFactory.toString(resourceXid) +
- "\nAssuming that the xid has been previously " +
- "forgotten.", xae);
- resourceState = RS_FORGOT;
- }
- }
- finally
- {
- lock();
- }
- }
-
- /**
- * Prepare the resource
- */
- public int prepare()
- throws XAException
- {
- int vote;
- unlock();
- if (trace)
- log.trace("Prepare: " + xaResource +
- " xid=" + xidFactory.toString(resourceXid));
- try
- {
- vote = xaResource.prepare(resourceXid);
-
- if (vote == XAResource.XA_OK)
- resourceState = RS_VOTE_OK;
- else if (vote == XAResource.XA_RDONLY)
- resourceState = RS_VOTE_READONLY;
- }
- catch (XAException e)
- {
- if (e.errorCode >= XAException.XA_RBBASE
- && e.errorCode <= XAException.XA_RBEND)
- {
- if (trace)
- log.trace("Got rollback vote from XAResource " + xaResource +
- " xid=" + xidFactory.toString(resourceXid) +
- ", tx=" + TransactionImpl.this.toString() +
- ", errorCode=" +
- TxUtils.getXAErrorCodeAsString(e.errorCode), e);
-
- resourceState = RS_ROLLEDBACK;
- }
- else
- throw e;
- }
- finally
- {
- lock();
- }
- return resourceState;
- }
-
- /**
- * Prepare the last resource
- */
- public void prepareLastResource()
- throws XAException
- {
- resourceState = RS_VOTE_OK;
- }
-
- /**
- * Commit the resource
- */
- public void commit(boolean onePhase)
- throws XAException
- {
- if (!onePhase && resourceState != RS_VOTE_OK)
- return; // Voted read-only at prepare phase.
-
- if (resourceSameRM != null)
- return; // This RM already committed.
-
- unlock();
- if (trace)
- log.trace("Commit: " + xaResource +
- " xid=" + xidFactory.toString(resourceXid) +
- " onePhase=" + onePhase);
- try
- {
- xaResource.commit(resourceXid, onePhase);
- committedResources++;
- resourceState = RS_COMMITTED;
- }
- catch (XAException e)
- {
- switch (e.errorCode)
- {
- case XAException.XA_HEURCOM:
- // Ignore this exception, as the heuristic outcome
- // is the one we wanted anyway.
- logXAException(e);
- if (trace)
- log.trace("Ignoring XAException.XA_HEURCOM" +
- " in XAResource.commit: " + xaResource +
- " xid=" + xidFactory.toString(resourceXid) +
- " onePhase=" + onePhase);
- forget();
- committedResources++;
- resourceState = RS_COMMITTED;
- break;
- case XAException.XAER_RMERR:
- case XAException.XA_HEURRB:
- rolledbackResources++;
- // fall through
- case XAException.XA_HEURMIX:
- case XAException.XA_HEURHAZ:
- resourceState = RS_HEUR_OUTCOME;
- throw e;
- case XAException.XAER_RMFAIL:
- case XAException.XA_RETRY:
- // stay in RS_VOTE_OK state - the commit will be retried
- throw e;
- case XAException.XAER_NOTA:
- case XAException.XAER_INVAL:
- case XAException.XAER_PROTO:
- default:
- // no point retrying
- resourceState = RS_ERROR;
- throw e;
- }
- }
- finally
- {
- if (xaResourceAccess != null && resourceState != RS_VOTE_OK)
- xaResourceAccess.release();
- lock();
- }
- }
-
- /**
- * Rollback the resource
- */
- public void rollback()
- throws XAException
- {
- if (resourceState == RS_VOTE_READONLY ||
- resourceState == RS_ROLLEDBACK || resourceState == RS_FORGOT)
- return;
-
- if (resourceSameRM != null)
- return; // This RM already rolled back.
-
- unlock();
- if (trace)
- log.trace("Rollback: " + xaResource +
- " xid=" + xidFactory.toString(resourceXid));
- try
- {
- xaResource.rollback(resourceXid);
- rolledbackResources++;
- resourceState = RS_ROLLEDBACK;
- }
- catch (XAException e)
- {
- switch (e.errorCode)
- {
- case XAException.XAER_RMERR:
- // Ignore this exception, as the transaction has been
- // rolled back, which is what we wanted anyway.
- if (trace)
- log.trace("Ignoring XAException.XAER_RMERR" +
- " in XAResource.rollback: " + xaResource +
- " xid=" + xidFactory.toString(resourceXid));
- rolledbackResources++;
- resourceState = RS_ROLLEDBACK;
- break;
- case XAException.XA_HEURRB:
- // Ignore this exception, as the heuristic outcome
- // is the one we wanted anyway.
- if (trace)
- log.trace("Ignoring XAException.XA_HEURRB" +
- " in XAResource.rollback: " + xaResource +
- " xid=" + xidFactory.toString(resourceXid));
- forget();
- rolledbackResources++;
- resourceState = RS_ROLLEDBACK;
- break;
- case XAException.XA_HEURCOM:
- committedResources++;
- case XAException.XA_HEURMIX:
- case XAException.XA_HEURHAZ:
- resourceState = RS_HEUR_OUTCOME;
- throw e;
- case XAException.XAER_RMFAIL:
- case XAException.XA_RETRY:
- // stay in RS_VOTE_OK state - the rollback will be retried
- throw e;
- case XAException.XAER_NOTA:
- case XAException.XAER_INVAL:
- case XAException.XAER_PROTO:
- default:
- // no point retrying
- resourceState = RS_ERROR;
- throw e;
- }
- }
- finally
- {
- if (xaResourceAccess != null && resourceState != RS_VOTE_OK)
- xaResourceAccess.release();
- lock();
- }
- }
- }
-
- /**
- * Represents a remote resource enlisted in the transaction.
- */
- private class EnlistedRemoteResource
- implements EnlistedResource
- {
- /**
- * The remote resource.
- */
- private Resource remoteResource;
-
- /**
- * The state of the resource.
- */
- private int resourceState;
-
- /**
- * The heuristic status of this resource
- */
- private int heurCode;
-
- /**
- * Creates a new <code>EnlistedRemoteResource</code>.
- */
- public EnlistedRemoteResource(Resource remoteResource)
- {
- this.remoteResource = remoteResource;
- resourceState = RS_NEW;
- heurCode = HEUR_NONE;
- }
-
- /**
- * Creates a new <code>EnlistedRemoteResource</code>.
- * This constructor is intended to be used during recovery only.
- */
- public EnlistedRemoteResource(Resource remoteResource, boolean prepared)
- {
- this.remoteResource = remoteResource;
- if (prepared)
- resourceState = RS_VOTE_OK;
- else
- resourceState = RS_NEW;
- heurCode = HEUR_NONE;
- }
-
- /**
- * Creates a resource in a heuristically completed state.
- * This constructor is intended to be used during recovery only.
- */
- public EnlistedRemoteResource(Resource remoteResource,
- boolean committed,
- int heurCode)
- {
- this.remoteResource = remoteResource;
- resourceState = (committed) ? RS_COMMITTED : RS_ROLLEDBACK;
- this.heurCode = heurCode;
- }
-
- /**
- * Gets the remote resource represented by this
- * <code>EnlistedRemoteResource</code> instance.
- */
- public Resource getRemoteResource()
- {
- return remoteResource;
- }
-
- /**
- * Gets the state of the remote resource represented by this
- * <code>EnlistedRemoteResource</code> instance.
- */
- public int getState()
- {
- return resourceState;
- }
-
- /**
- * Prepare the resource
- */
- public int prepare()
- throws RemoteException,
- TransactionAlreadyPreparedException,
- HeuristicMixedException,
- HeuristicHazardException
- {
- Vote vote = null;
- unlock();
- try
- {
- vote = remoteResource.prepare();
- }
- finally
- {
- lock();
- }
-
- if (vote == Vote.COMMIT)
- resourceState = RS_VOTE_OK;
- else if (vote == Vote.READONLY)
- resourceState = RS_VOTE_READONLY;
- else /* (vote == Vote.ROLLBACK) */
- resourceState = RS_ROLLEDBACK;
-
- return resourceState;
- }
-
- /**
- * Commit the resource
- *
- * @throws RemoteException
- * @throws HeuristicHazardException
- * @throws HeuristicMixedException
- * @throws HeuristicRollbackException
- * @throws TransactionNotPreparedException
- *
- */
- public void commit(boolean onePhase)
- throws RemoteException,
- TransactionNotPreparedException,
- HeuristicRollbackException,
- HeuristicMixedException,
- HeuristicHazardException
- {
- if (trace)
- log.trace("Committing resource " + remoteResource +
- " state=" + resourceState);
-
- if (!onePhase && resourceState != RS_VOTE_OK)
- return; // Voted read-only at prepare phase.
-
- unlock();
- try
- {
- if (onePhase)
- remoteResource.commitOnePhase();
- else
- remoteResource.commit();
-
- committedResources++;
- resourceState = RS_COMMITTED;
- }
- catch (TransactionRolledbackException e)
- {
- rolledbackResources++;
- resourceState = RS_ROLLEDBACK;
- throw e;
- }
- catch (RemoteException e)
- {
- // stay in RS_VOTE_OK state - the commit will be retried
- throw e;
- }
- catch (TransactionNotPreparedException e)
- {
- resourceState = RS_ERROR;
- throw e;
- }
- catch (HeuristicRollbackException e)
- {
- rolledbackResources++;
- resourceState = RS_HEUR_OUTCOME;
- throw e;
- }
- catch (HeuristicMixedException e)
- {
- resourceState = RS_HEUR_OUTCOME;
- throw e;
- }
- catch (HeuristicHazardException e)
- {
- resourceState = RS_HEUR_OUTCOME;
- throw e;
- }
- finally
- {
- lock();
- }
- }
-
- /**
- * Rollback the resource
- */
- public void rollback()
- throws RemoteException,
- HeuristicCommitException,
- HeuristicMixedException,
- HeuristicHazardException
- {
- if (resourceState == RS_VOTE_READONLY ||
- resourceState == RS_ROLLEDBACK || resourceState == RS_FORGOT)
- return;
-
- unlock();
- try
- {
- remoteResource.rollback();
- rolledbackResources++;
- resourceState = RS_ROLLEDBACK;
- }
- catch (TransactionRolledbackException e)
- {
- rolledbackResources++;
- resourceState = RS_ROLLEDBACK;
- throw e;
- }
- catch (RemoteException e)
- {
- // stay in RS_VOTE_OK state - the rollback will be retried
- throw e;
- }
- catch (HeuristicCommitException e)
- {
- committedResources++;
- resourceState = RS_HEUR_OUTCOME;
- throw e;
- }
- catch (HeuristicMixedException e)
- {
- resourceState = RS_HEUR_OUTCOME;
- throw e;
- }
- catch (HeuristicHazardException e)
- {
- resourceState = RS_HEUR_OUTCOME;
- throw e;
- }
- finally
- {
- lock();
- }
- }
-
- /**
- * Remember that this resource has a heuristic outcome.
- */
- public void remember(int heuristicCode)
- {
- heurCode = heuristicCode;
- if (remoteResourcesWithHeuristicDecisions == null)
- remoteResourcesWithHeuristicDecisions = new ArrayList();
- remoteResourcesWithHeuristicDecisions.add(this);
- }
-
- /**
- * Get the heuristic status of this resource.
- */
- public int getHeuristicCode()
- {
- return heurCode;
- }
-
- /**
- * Forget the resource
- */
- public void forget()
- {
- unlock();
- if (trace)
- log.trace("Forget: " + remoteResource);
- try
- {
- remoteResource.forget();
- resourceState = RS_FORGOT;
- }
- catch (NoSuchObjectException e)
- {
- if (trace)
- log.trace("NoSuchObjectException in forget: remoteResource=" +
- remoteResource + "\nAssuming that the resource has " +
- "been previously forgotten.", e);
- }
- catch (RemoteException e)
- {
- if (trace)
- log.trace("RemoteException in forget: remoteResource=" +
- remoteResource + "\nThe resource still needs to be " +
- "forgotten.", e);
- }
- finally
- {
- lock();
- }
- resourceState = RS_FORGOT;
- }
-
- }
-
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/TransactionManagerInitializer.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/TransactionManagerInitializer.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/TransactionManagerInitializer.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,692 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm;
-
-import java.util.HashMap;
-import java.util.Hashtable;
-import java.util.Map;
-import javax.naming.Context;
-import javax.naming.InitialContext;
-import javax.naming.Name;
-import javax.naming.Reference;
-import javax.naming.spi.ObjectFactory;
-import javax.transaction.TransactionManager;
-import javax.transaction.xa.XAException;
-import org.jboss.logging.Logger;
-import org.jboss.tm.integrity.TransactionIntegrityFactory;
-import org.jboss.tm.recovery.RecoveryLogger;
-
-/**
- * This is a JMX service which manages the TransactionManager.
- * The service creates it and binds a Reference to it into JNDI.
- *
- * @see TxManager
- * @author <a href="mailto:rickard.oberg at telkel.com">Rickard Oberg</a>
- * @author <a href="mailto:osh at sparre.dk">Ole Husgaard</a>
- * @author <a href="mailto:toby.allsopp at peace.com">Toby Allsopp</a>
- * @author <a href="reverbel at ime.usp.br">Francisco Reverbel</a>
- * @version $Revision$
- *
- * @jmx.mbean extends="org.jboss.system.ServiceMBean"
- */
-public class TransactionManagerInitializer implements XAExceptionFormatter, ObjectFactory
-{
- private static Logger log = Logger.getLogger(TransactionManagerInitializer.class);
-
- // Constants -----------------------------------------------------
- public static String JNDI_NAME = "java:/TransactionManager";
- public static String JNDI_IMPORTER = "java:/TransactionPropagationContextImporter";
- public static String JNDI_EXPORTER = "java:/TransactionPropagationContextExporter";
-
- // Attributes ----------------------------------------------------
-
- private boolean globalIdsEnabled = false; // flag duplicated in TM
-
- /** Whether to interrupt threads at transaction timeout */
- private boolean interruptThreads = false;
-
- private int timeout = 300; // default tx timeout, dupl. in TM when it exists.
-
- private int completionRetryLimit = 0;
-
- private int completionRetryTimeout = 1;
-
- private int xaRetryTimeout;
-
- private int preparedTimeout;
-
- private boolean rootBranchRemembersHeuristicDecisions = true;
-
- private boolean reportHeuristicHazardAsHeuristicMixed = false;
-
- private final Map xaExceptionFormatters = new HashMap();
-
- private RecoveryLogger recoveryLogger;
-
- private XidFactoryBase xidFactory;
-
- private TransactionIntegrityFactory integrityFactory;
-
- private InitialContext initialContext;
-
- protected Hashtable initialContextProperties;
-
- // Static --------------------------------------------------------
-
- static TxManager tm;
-
- // ServiceMBeanSupport overrides ---------------------------------
-
- public void setInitialContextProperties(Hashtable initialContextProperties)
- {
- this.initialContextProperties = initialContextProperties;
- }
-
-
- public void start() throws Exception
- {
- if (initialContextProperties == null) initialContext = new InitialContext();
- else initialContext = new InitialContext(initialContextProperties);
-
- TransactionImpl.xidFactory = xidFactory;
- TransactionImpl.xaExceptionFormatter = this;
-
- // Get a reference to the TxManager singleton.
- tm = TxManager.getInstance();
- // Set its default timeout.
- tm.setDefaultTransactionTimeout(timeout);
- // Set the TxManager limit and timout for retrying a completion operation
- // before reporting a heuristic hazard outcome.
- tm.setCompletionRetryLimit(completionRetryLimit);
- tm.setCompletionRetryTimeout(completionRetryTimeout);
- // Set the TxManager timouts for retrying a XA operation and
- // for a foreign transaction to remain in the prepared state.
- tm.setXARetryTimeout(xaRetryTimeout);
- tm.setPreparedTimeout(preparedTimeout);
- // Set the TxManager flags for remembering heuristic decisions
- // at the root branch and for heuristic hazard reporting.
- tm.setRootBranchRemembersHeuristicDecisions(
- rootBranchRemembersHeuristicDecisions);
- tm.setReportHeuristicHazardAsHeuristicMixed(
- reportHeuristicHazardAsHeuristicMixed);
- // Initialize its globalIdsEnabled flag.
- tm.setGlobalIdsEnabled(globalIdsEnabled);
- tm.setInterruptThreads(interruptThreads);
- if (integrityFactory != null)
- tm.setTransactionIntegrity(integrityFactory.createTransactionIntegrity());
- else
- tm.setTransactionIntegrity(null);
-
- // Bind reference to TM in JNDI
- // Our TM also implement the tx importer and exporter
- // interfaces, so we bind it under those names too.
- // Other transaction managers may have seperate
- // implementations of these objects, so they are
- // accessed under separate names.
- bindRef(JNDI_NAME, "org.jboss.tm.TxManager");
- bindRef(JNDI_IMPORTER, "org.jboss.tm.TransactionPropagationContextImporter");
- bindRef(JNDI_EXPORTER, "org.jboss.tm.TransactionPropagationContextFactory");
- }
-
- public void stop()
- {
- try
- {
- // Remove TM, importer and exporter from JNDI
- Context ctx = initialContext;
- ctx.unbind(JNDI_NAME);
- ctx.unbind(JNDI_IMPORTER);
- ctx.unbind(JNDI_EXPORTER);
- }
- catch (Exception e)
- {
- log.error("Failed to clear JNDI bindings", e);
- }
- }
-
- /**
- * Set the Recover logger
- *
- * @param recoveryLogger
- */
- public void setRecoveryLogger(RecoveryLogger recoveryLogger)
- {
- this.recoveryLogger = recoveryLogger;
- // inject the logger into the TxManager
- TxManager.getInstance().setRecoveryLogger(this.recoveryLogger);
- }
-
-
- /**
- * Set the Transaciton integrity factory
- *
- * @param factory the transaction integrity factory
- */
- public void setTransactionIntegrityFactory(TransactionIntegrityFactory factory)
- {
- this.integrityFactory = factory;
- if (tm != null)
- {
- if (factory != null)
- tm.setTransactionIntegrity(factory.createTransactionIntegrity());
- else
- tm.setTransactionIntegrity(null);
- }
- }
-
- /**
- * Gets the "global ids enabled" flag.
- *
- * @return an <code>boolean</code> value
- */
- public boolean getGlobalIdsEnabled()
- {
- return globalIdsEnabled;
- }
-
- /**
- * Sets the "global ids enabled" flag.
- *
- * @param newValue an <code>boolean</code> value
- */
- public void setGlobalIdsEnabled(boolean newValue)
- {
- globalIdsEnabled = newValue;
- if (tm != null) // Update TM setting
- tm.setGlobalIdsEnabled(newValue);
- }
-
- /**
- * Is thread interruption enabled at transaction timeout
- *
- * @return true for interrupt threads, false otherwise
- */
- public boolean isInterruptThreads()
- {
- return interruptThreads;
- }
-
- /**
- * Enable/disable thread interruption at transaction timeout.
- *
- * @param interruptThreads pass true to interrupt threads, false otherwise
- */
- public void setInterruptThreads(boolean interruptThreads)
- {
- this.interruptThreads = interruptThreads;
- if (tm != null)
- tm.setInterruptThreads(interruptThreads);
- }
-
- /**
- * Describe <code>getTransactionTimeout</code> method here.
- *
- * @return an <code>int</code> value
- */
- public int getTransactionTimeout()
- {
- if (tm != null) // Get timeout value from TM (in case it was changed).
- timeout = tm.getDefaultTransactionTimeout();
- return timeout;
- }
-
- /**
- * Describe <code>setTransactionTimeout</code> method here.
- *
- * @param timeout an <code>int</code> value
- * @jmx:managed-attribute
- */
- public void setTransactionTimeout(int timeout)
- {
- this.timeout = timeout;
- if (tm != null) // Update TM default timeout
- tm.setDefaultTransactionTimeout(timeout);
- }
-
- /**
- * Sets the completion retry limit. This is the maximum number of times that
- * the transaction manager retries a completion operation (either commit or
- * rollback) on a resource (either a remote <code>Resource</code> or an
- * <code>XAResource</code>) that raised a transient exception. Whoever called
- * the transaction manager is blocked while the completion retries are
- * performed. If the completion retry limit is reached, the transaction
- * manager abandons the retries and throws a heuristic hazard exception.
- *
- * @param maxCompletionRetries the completion retry limit.
- */
- public void setCompletionRetryLimit(int maxCompletionRetries)
- {
- this.completionRetryLimit = maxCompletionRetries;
- if (tm != null) // Update TM setting
- tm.setCompletionRetryLimit(maxCompletionRetries);
- }
-
- /**
- * Gets the completion retry limit. This is the maximum number of times that
- * the transaction manager retries a completion operation (either commit or
- * rollback) on a resource (either a remote <code>Resource</code> or an
- * <code>XAResource</code>) that raised a transient exception. Whoever called
- * the transaction manager is blocked while the completion retries are
- * performed. If the completion retry limit is reached, the transaction
- * manager abandons the retries and throws a heuristic hazard exception.
- *
- * @return the completion retry limit.
- */
- public int getCompletionRetryLimit()
- {
- return completionRetryLimit;
- }
-
- /**
- * Sets the completion retry timeout. The completion retry timeout is the
- * number of seconds that the transaction manager waits before retrying a
- * completion operation (either commit or rollback) on a resource (either a
- * remote <code>Resource</code> or an <code>XAResource</code>) that raised a
- * transient exception. This is a blocking timeout (whoever called the
- * transaction manager is blocked until the commit or rollback is retried)
- * and is applicable if the transaction manager did not report a heuristic
- * hazard for the transaction. If a heuristic hazard has been reported, then
- * the applicable timouts are the non-blocking ones: the XA retry timeout and
- * the prepared timeout.
- *
- * @param seconds the timeout (in seconds) for retrying a completion
- * operation after a transient exception and before the
- * transaction manager reports a heuristic hazard.
- */
- public void setCompletionRetryTimeout(int seconds)
- {
- this.completionRetryTimeout = seconds;
- if (tm != null) // Update TM setting
- tm.setCompletionRetryTimeout(seconds);
- }
-
- /**
- * Gets the completion retry timeout. The completion retry timeout is the
- * number of seconds that the transaction manager waits before retrying a
- * completion operation (either commit or rollback) on a resource (either a
- * remote <code>Resource</code> or an <code>XAResource</code>) that raised a
- * transient exception. This is a blocking timeout (whoever called the
- * transaction manager is blocked until the commit or rollback is retried)
- * and is applicable if the transaction manager did not report a heuristic
- * hazard for the transaction. If a heuristic hazard has been reported, then
- * the applicable timouts are the non-blocking ones: the XA retry timeout and
- * the prepared timeout.
- *
- * @return the timeout (in seconds) for retrying a completion operation
- * after a transient exception and before the transaction manager
- * reports a heuristic hazard.
- */
- public int getCompletionRetryTimeout()
- {
- return completionRetryTimeout;
- }
-
- /**
- * Sets the XA retry timeout.
- *
- * @param xaRetryTimeout the timeout (in seconds) for retrying operations on
- * XA resources.
- */
- public void setXARetryTimeout(int xaRetryTimeout)
- {
- this.xaRetryTimeout = xaRetryTimeout;
- if (tm != null) // Update TM setting
- tm.setXARetryTimeout(xaRetryTimeout);
- }
-
- /**
- * Gets the XA retry timeout.
- *
- * @return the timeout (in seconds) for retrying operations on XA resources.
- */
- public int getXARetryTimeout()
- {
- return xaRetryTimeout;
- }
-
- /**
- * Sets the prepared timeout. A transaction branch that is the prepared
- * state waits for an amount of time equal to the prepared timeout before
- * generating a call to <code>replayCompletion</code> on its recovery
- * coordinator.
- *
- * @param preparedTimeout the timeout (in seconds) for a transaction branch
- * in the prepared state.
- */
- public void setPreparedTimeout(int preparedTimeout)
- {
- this.preparedTimeout = preparedTimeout;
- if (tm != null) // Update TM setting
- tm.setPreparedTimeout(preparedTimeout);
- }
-
- /**
- * Gets the prepared timeout. A transaction branch that is the prepared
- * state waits for an amount of time equal to the prepared timeout before
- * generating a call to <code>replayCompletion</code> on its recovery
- * coordinator.
- *
- * @return the timeout (in seconds) for a transaction branch in the prepared
- * state.
- */
- public int getPreparedTimeout()
- {
- return preparedTimeout;
- }
-
- /**
- * Sets the boolean attribute "root branch remembers heuristic decisions".
- * If this attribute is true, the root branch remembers a heuristically
- * completed transaction until explicitly told (through a call to the MBean
- * operation <code>forget</code>) to forget that transaction. If this
- * attribute is false, the root branch immediately forgets a transaction
- * when the transaction completes.
- *
- * @param newValue true if the root branch should remember heuristic
- * decisions, false otherwise.
- */
- public void setRootBranchRemembersHeuristicDecisions(boolean newValue)
- {
- this.rootBranchRemembersHeuristicDecisions = newValue;
- if (tm != null) // Update TM setting
- tm.setRootBranchRemembersHeuristicDecisions(newValue);
- }
-
- /**
- * Gets the boolean attribute "root branch remembers heuristic decisions".
- * If this attribute is true, the root branch remembers a heuristically
- * completed transaction until explicitly told (through a call to the MBean
- * operation <code>forget</code>) to forget that transaction. If this
- * attribute is false, the root branch immediately forgets a transaction
- * when the transaction completes.
- *
- * @return true if the root branch remember heuristic decisions,
- * false otherwise.
- */
- public boolean isRootBranchRemembersHeuristicDecisions()
- {
- return rootBranchRemembersHeuristicDecisions;
- }
-
- /**
- * Sets the boolean attribute "report heuristic hazard as heuristic mixed".
- * If this attribute is true, each of the commit methods of the JTA API
- * (<code>javax.transaction.Transaction.commit()</code>,
- * <code>javax.transaction.TransactionManager.commit()</code>, and
- * <code>javax.transaction.UserTransaction.commit()</code>) throws a
- * <code>HeuristicMixedException</code> to report a heuristic hazard to its
- * caller. If the attribute is false, those methods do not report heuristic
- * hazards to their callers. In any case, transactions with heuristic hazard
- * status are listed by the MBean operation
- * <code>listHeuristicallyCompletedTransactions()</code>.
- *
- * @param newValue true if a JTA commit should throw
- * <code>HeuristicMixedException</code> to report a heuristic hazard
- * to its caller, or false if a JTA commit should not report a
- * heuristic hazard to its caller.
- */
- public void setReportHeuristicHazardAsHeuristicMixed(boolean newValue)
- {
- this.reportHeuristicHazardAsHeuristicMixed = newValue;
- if (tm != null) // Update TM setting
- tm.setReportHeuristicHazardAsHeuristicMixed(newValue);
-
- }
-
- /**
- * Gets the boolean attribute "report heuristic hazard as heuristic mixed".
- * If this attribute is true, each of the commit methods of the JTA API
- * (<code>javax.transaction.Transaction.commit()</code>,
- * <code>javax.transaction.TransactionManager.commit()</code>, and
- * <code>javax.transaction.UserTransaction.commit()</code>) throws a
- * <code>HeuristicMixedException</code> to report a heuristic hazard to its
- * caller. If the attribute is false, those methods do not report heuristic
- * hazards to their callers. In any case, transactions with heuristic hazard
- * status are listed by the MBean operation
- * <code>listHeuristicallyCompletedTransactions()</code>.
- *
- * @return true if a JTA commit throws <code>HeuristicMixedException</code>
- * to report a heuristic hazard to its caller, or false if a JTA
- * commit does not report a heuristic hazard to its caller.
- */
- boolean isReportHeuristicHazardAsHeuristicMixed()
- {
- return reportHeuristicHazardAsHeuristicMixed;
- }
-
- /**
- * mbean get-set pair for field xidFactory
- * Get the value of xidFactory
- * @return value of xidFactory
- *
- */
- public XidFactoryBase getXidFactory()
- {
- return xidFactory;
- }
-
- /**
- * Set the value of xidFactory
- * @param xidFactory Value to assign to xidFactory
- *
- */
- public void setXidFactory(XidFactoryBase xidFactory)
- {
- this.xidFactory = xidFactory;
- }
-
-
- /**
- * mbean get-set pair for field transactionManager
- * Get the value of transactionManager
- * @return value of transactionManager
- *
- */
- public TransactionManager getTransactionManager()
- {
- return tm;
- }
-
- /**
- * Get the xa terminator
- *
- * @return the xa terminator
- */
- public JBossXATerminator getXATerminator()
- {
- return tm;
- }
-
- /**
- * Counts the number of transactions
- *
- * @return the number of active transactions
- *
- */
- public long getTransactionCount()
- {
- return tm.getTransactionCount();
- }
- /** The number of commits.
- *
- * @return the number of transactions that have been committed
- *
- */
- public long getCommitCount()
- {
- return tm.getCommitCount();
- }
- /** The number of rollbacks.
- *
- * @return the number of transactions that have been rolled back
- *
- */
- public long getRollbackCount()
- {
- return tm.getRollbackCount();
- }
-
- /**
- * Lists the in-doubt transactions.
- *
- * @return a string with a text listing of in-doubt transactions.
- */
- public String listInDoubtTransactions()
- {
- return tm.listInDoubtTransactions();
- }
-
- /**
- * Heuristically commits an in-doubt transaction.
- *
- * @param localTransactionId the local id of the in-doubt transaction to be
- * heuristically committed.
- */
- public void heuristicallyCommit(long localTransactionId)
- {
- tm.heuristicallyCommit(localTransactionId);
- }
-
- /**
- * Heuristically commits all in-doubt transactions.
- */
- public void heuristicallyCommitAll()
- {
- tm.heuristicallyCommitAll();
- }
-
- /**
- * Heuristically rolls back an in-doubt transaction.
- *
- * @param localTransactionId the local id of the in-doubt transaction to be
- * heuristically rolled back.
- */
- public void heuristicallyRollback(long localTransactionId)
- {
- tm.heuristicallyRollback(localTransactionId);
- }
-
- /**
- * Heuristically rolls back all in-doubt transactions.
- */
- public void heuristicallyRollbackAll()
- {
- tm.heuristicallyRollbackAll();
- }
-
- /**
- * Lists the heuristically completed transactions coordinated by this
- * transaction manager. A transaction that was heuristically completed
- * by a call to <code>heuristicallyCommit(long localTransactionId)</code>,
- * <code>heuristicallyCommitAll()</code>,
- * <code>heuristicallyRollback(long localTransactionId)</code>, or
- * <code>heuristicallyRollbackAll()</code> does not appear in the listing,
- * as that transaction had a foreign coordinator.
- *
- * @return a string with a text listing of heuristically completed
- * transactions.
- */
- public String listHeuristicallyCompletedTransactions()
- {
- return tm.listHeuristicallyCompletedTransactions();
- }
-
- /**
- * Forgets a heuristically completed transaction coordinated by this
- * transaction manager.
- *
- * @param localTransactionId the local id of a heuristically completed
- * transaction coordinated by this transaction
- * manager.
- */
- public void forget(long localTransactionId)
- {
- tm.forget(localTransactionId);
- }
-
- /**
- * Forgets all heuristically completed transactions coordinated by this
- * transaction manager.
- */
- public void forgetAll()
- {
- tm.forgetAll();
- }
-
- /**
- * The <code>registerXAExceptionFormatter</code> method
- *
- * @param clazz a <code>Class</code> value
- * @param formatter a <code>XAExceptionFormatter</code> value
- *
- */
- public void registerXAExceptionFormatter(Class clazz, XAExceptionFormatter formatter)
- {
- xaExceptionFormatters.put(clazz, formatter);
- }
-
- /**
- * The <code>unregisterXAExceptionFormatter</code> method
- *
- * @param clazz a <code>Class</code> value
- *
- */
- public void unregisterXAExceptionFormatter(Class clazz)
- {
- xaExceptionFormatters.remove(clazz);
- }
-
- public void formatXAException(XAException xae, Logger log)
- {
- Class clazz = xae.getClass();
- while (clazz != XAException.class)
- {
- XAExceptionFormatter formatter = (XAExceptionFormatter) xaExceptionFormatters.get(clazz);
- if (formatter != null)
- {
- formatter.formatXAException(xae, log);
- return;
- } // end of if ()
- clazz = clazz.getSuperclass();
- }
- }
-
- // ObjectFactory implementation ----------------------------------
-
- public Object getObjectInstance(Object obj, Name name,
- Context nameCtx, Hashtable environment)
- throws Exception
- {
- // Return the transaction manager
- return tm;
- }
-
-
- // Private -------------------------------------------------------
-
- private void bindRef(String jndiName, String className)
- throws Exception
- {
- Reference ref = new Reference(className, getClass().getName(), null);
- initialContext.bind(jndiName, ref);
- }
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/TransactionManagerService.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/TransactionManagerService.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/TransactionManagerService.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,284 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm;
-
-import javax.management.ObjectName;
-import javax.transaction.TransactionManager;
-
-import org.jboss.system.ServiceMBeanSupport;
-import org.jboss.tm.integrity.TransactionIntegrityFactory;
-import org.jboss.tm.recovery.RecoveryLogger;
-import org.jboss.tm.recovery.RecoveryLoggerInstance;
-
-/**
- * This is a JMX service which manages the TransactionManager.
- * The service creates it and binds a Reference to it into JNDI.
- *
- * @see TxManager
- * @author <a href="mailto:rickard.oberg at telkel.com">Rickard Oberg</a>
- * @author <a href="mailto:osh at sparre.dk">Ole Husgaard</a>
- * @author <a href="mailto:toby.allsopp at peace.com">Toby Allsopp</a>
- * @author <a href="reverbel at ime.usp.br">Francisco Reverbel</a>
- * @version $Revision$
- *
- * @jmx.mbean extends="org.jboss.system.ServiceMBean"
- */
-public class TransactionManagerService
- extends ServiceMBeanSupport
- implements TransactionManagerServiceMBean
-{
- private ObjectName xidFactory;
-
- private TransactionManagerInitializer initializer = new TransactionManagerInitializer();
-
- // Constants -----------------------------------------------------
- public static String JNDI_NAME = "java:/TransactionManager";
- public static String JNDI_IMPORTER = "java:/TransactionPropagationContextImporter";
- public static String JNDI_EXPORTER = "java:/TransactionPropagationContextExporter";
-
- protected void startService()
- throws Exception
- {
- XidFactoryMBean xidFactoryObj = (XidFactoryMBean) getServer().getAttribute(xidFactory, "Instance");
- initializer.setXidFactory(xidFactoryObj);
- initializer.start();
- }
-
- protected void stopService()
- {
- initializer.stop();
- }
-
- /**
- * Set the Recover logger
- *
- * @param recoveryLogger
- * @jmx:managed-attribute
- */
- public void setRecoveryLogger(RecoveryLoggerInstance recoveryLogger)
- {
- initializer.setRecoveryLogger(recoveryLogger.getInstance());
- }
-
- /**
- * Set the Transaction integrity factory
- *
- * @param factory the factory
- */
- public void setTransactionIntegrityFactory(TransactionIntegrityFactory factory)
- {
- initializer.setTransactionIntegrityFactory(factory);
- }
-
- /**
- * mbean get-set pair for field xidFactory
- * Get the value of xidFactory
- * @return value of xidFactory
- *
- * @jmx:managed-attribute
- */
- public ObjectName getXidFactory()
- {
- return xidFactory;
- }
-
- /**
- * Set the value of xidFactory
- * @param xidFactory Value to assign to xidFactory
- *
- * @jmx:managed-attribute
- */
- public void setXidFactory(ObjectName xidFactory)
- {
- this.xidFactory = xidFactory;
- }
-
- public void setRecoveryLogger(RecoveryLogger recoveryLogger)
- {
- initializer.setRecoveryLogger(recoveryLogger);
- }
-
- public boolean getGlobalIdsEnabled()
- {
- return initializer.getGlobalIdsEnabled();
- }
-
- public void setGlobalIdsEnabled(boolean newValue)
- {
- initializer.setGlobalIdsEnabled(newValue);
- }
-
- public boolean isInterruptThreads()
- {
- return initializer.isInterruptThreads();
- }
-
- public void setInterruptThreads(boolean interruptThreads)
- {
- initializer.setInterruptThreads(interruptThreads);
- }
-
- public int getTransactionTimeout()
- {
- return initializer.getTransactionTimeout();
- }
-
- public void setTransactionTimeout(int timeout)
- {
- initializer.setTransactionTimeout(timeout);
- }
-
- public int getCompletionRetryLimit()
- {
- return initializer.getCompletionRetryLimit();
- }
-
- public void setCompletionRetryLimit(int limit)
- {
- initializer.setCompletionRetryLimit(limit);
- }
-
- public int getCompletionRetryTimeout()
- {
- return initializer.getCompletionRetryTimeout();
- }
-
- public void setCompletionRetryTimeout(int timeout)
- {
- initializer.setCompletionRetryTimeout(timeout);
- }
-
- public int getXARetryTimeout()
- {
- return initializer.getXARetryTimeout();
- }
-
- public void setXARetryTimeout(int timeout)
- {
- initializer.setXARetryTimeout(timeout);
- }
-
- public int getPreparedTimeout()
- {
- return initializer.getPreparedTimeout();
- }
-
- public void setPreparedTimeout(int timeout)
- {
- initializer.setPreparedTimeout(timeout);
- }
-
- public boolean isRootBranchRemembersHeuristicDecisions()
- {
- return initializer.isRootBranchRemembersHeuristicDecisions();
- }
-
- public void setRootBranchRemembersHeuristicDecisions(boolean newValue)
- {
- initializer.setRootBranchRemembersHeuristicDecisions(newValue);
- }
-
- public boolean isReportHeuristicHazardAsHeuristicMixed()
- {
- return initializer.isReportHeuristicHazardAsHeuristicMixed();
- }
-
- public void setReportHeuristicHazardAsHeuristicMixed(boolean newValue)
- {
- initializer.setReportHeuristicHazardAsHeuristicMixed(newValue);
- }
-
- public TransactionManager getTransactionManager()
- {
- return initializer.getTransactionManager();
- }
-
- public JBossXATerminator getXATerminator()
- {
- return initializer.getXATerminator();
- }
-
- public long getTransactionCount()
- {
- return initializer.getTransactionCount();
- }
-
- public long getCommitCount()
- {
- return initializer.getCommitCount();
- }
-
- public long getRollbackCount()
- {
- return initializer.getRollbackCount();
- }
-
- public String listInDoubtTransactions()
- {
- return initializer.listInDoubtTransactions();
- }
-
- public void heuristicallyCommit(long localTransactionId)
- {
- initializer.heuristicallyCommit(localTransactionId);
- }
-
- public void heuristicallyCommitAll()
- {
- initializer.heuristicallyCommitAll();
- }
-
- public void heuristicallyRollback(long localTransactionId)
- {
- initializer.heuristicallyRollback(localTransactionId);
- }
-
- public void heuristicallyRollbackAll()
- {
- initializer.heuristicallyRollbackAll();
- }
-
- public String listHeuristicallyCompletedTransactions()
- {
- return initializer.listHeuristicallyCompletedTransactions();
- }
-
- public void forget(long localTransactionId)
- {
- initializer.forget(localTransactionId);
- }
-
- public void forgetAll()
- {
- initializer.forgetAll();
- }
-
- public void registerXAExceptionFormatter(Class clazz, XAExceptionFormatter formatter)
- {
- initializer.registerXAExceptionFormatter(clazz, formatter);
- }
-
- public void unregisterXAExceptionFormatter(Class clazz)
- {
- initializer.unregisterXAExceptionFormatter(clazz);
- }
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/TransactionManagerServiceMBean.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/TransactionManagerServiceMBean.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/TransactionManagerServiceMBean.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,375 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm;
-
-import javax.management.ObjectName;
-
-import org.jboss.mx.util.ObjectNameFactory;
-import org.jboss.system.ServiceMBean;
-import org.jboss.tm.integrity.TransactionIntegrityFactory;
-import org.jboss.tm.recovery.RecoveryLoggerInstance;
-
-/**
- * TransactionManagerService MBean interface.
- *
- * @see TxManager
- * @version $Revision$
- */
-public interface TransactionManagerServiceMBean extends ServiceMBean, TransactionManagerFactory
-{
- ObjectName OBJECT_NAME = ObjectNameFactory.create("jboss:service=TransactionManager");
-
- /**
- * Set the Recover logger
- * @param recoveryLogger
- */
- void setRecoveryLogger(RecoveryLoggerInstance recoveryLogger);
-
- /**
- * Set the Integrity checker factory
- *
- * @param factory the integrity checker factory
- */
- void setTransactionIntegrityFactory(TransactionIntegrityFactory factory);
-
- /**
- * Describe <code>getGlobalIdsEnabled</code> method here.
- * @return an <code>boolean</code> value
- */
- boolean getGlobalIdsEnabled();
-
- /**
- * Describe <code>setGlobalIdsEnabled</code> method here.
- * @param newValue an <code>boolean</code> value
- */
- void setGlobalIdsEnabled(boolean newValue);
-
- /**
- * Is thread interruption enabled at transaction timeout
- * @return true for interrupt threads, false otherwise
- */
- boolean isInterruptThreads();
-
- /**
- * Enable/disable thread interruption at transaction timeout.
- * @param interruptThreads pass true to interrupt threads, false otherwise
- */
- void setInterruptThreads(boolean interruptThreads);
-
- /**
- * Describe <code>getTransactionTimeout</code> method here.
- * @return an <code>int</code> value
- */
- int getTransactionTimeout();
-
- /**
- * Describe <code>setTransactionTimeout</code> method here.
- * @param timeout an <code>int</code> value
- */
- void setTransactionTimeout(int timeout);
-
- /**
- * Gets the completion retry limit. This is the maximum number of times that
- * the transaction manager retries a completion operation (either commit or
- * rollback) on a resource (either a remote <code>Resource</code> or an
- * <code>XAResource</code>) that raised a transient exception. Whoever called
- * the transaction manager is blocked while the completion retries are
- * performed. If the completion retry limit is reached, the transaction
- * manager abandons the retries and throws a heuristic hazard exception.
- *
- * @return the completion retry limit.
- */
- int getCompletionRetryLimit();
-
- /**
- * Sets the completion retry limit. This is the maximum number of times that
- * the transaction manager retries a completion operation (either commit or
- * rollback) on a resource (either a remote <code>Resource</code> or an
- * <code>XAResource</code>) that raised a transient exception. Whoever called
- * the transaction manager is blocked while the completion retries are
- * performed. If the completion retry limit is reached, the transaction
- * manager abandons the retries and throws a heuristic hazard exception.
- *
- * @param maxCompletionRetries the completion retry limit.
- */
- void setCompletionRetryLimit(int maxCompletionRetries);
-
- /**
- * Gets the completion retry timeout. The completion retry timeout is the
- * number of seconds that the transaction manager waits before retrying a
- * completion operation (either commit or rollback) on a resource (either a
- * remote <code>Resource</code> or an <code>XAResource</code>) that raised a
- * transient exception. This is a blocking timeout (whoever called the
- * transaction manager is blocked until the commit or rollback is retried)
- * and is applicable if the transaction manager did not report a heuristic
- * hazard for the transaction. If a heuristic hazard has been reported, then
- * the applicable timouts are the non-blocking ones: the XA retry timeout and
- * the prepared timeout.
- *
- * @return the timeout (in seconds) for retrying a completion operation
- * after a transient exception and before the transaction manager
- * reports a heuristic hazard.
- */
- int getCompletionRetryTimeout();
-
- /**
- * Sets the completion retry timeout. The completion retry timeout is the
- * number of seconds that the transaction manager waits before retrying a
- * completion operation (either commit or rollback) on a resource (either a
- * remote <code>Resource</code> or an <code>XAResource</code>) that raised a
- * transient exception. This is a blocking timeout (whoever called the
- * transaction manager is blocked until the commit or rollback is retried)
- * and is applicable if the transaction manager did not report a heuristic
- * hazard for the transaction. If a heuristic hazard has been reported, then
- * the applicable timouts are the non-blocking ones: the XA retry timeout and
- * the prepared timeout.
- *
- * @param seconds the timeout (in seconds) for retrying a completion
- * operation after a transient exception and before the
- * transaction manager reports a heuristic hazard.
- */
- void setCompletionRetryTimeout(int seconds);
-
- /**
- * Gets the XA retry timeout. After reaching the completion retry limit and
- * reporting a heuristic hazard to its caller, the transaction manager will
- * still attempt to commit or rollback an XA resource that raised a
- * transient exception. This is the time interval (in seconds) between XA
- * completion retries that is applicable if a heuristic hazard has been
- * reported for a transaction.
- *
- * @return the timeout (in seconds) for retrying commit or rollback
- * operations on XA resources.
- */
- int getXARetryTimeout();
-
- /**
- * Sets the XA retry timeout. After reaching the completion retry limit and
- * reporting a heuristic hazard to its caller, the transaction manager will
- * still attempt to commit or rollback an XA resource that raised a
- * transient exception. This is the time interval (in seconds) between XA
- * completion retries that is applicable if a heuristic hazard has been
- * reported for a transaction.
- *
- * @param seconds the timeout (in seconds) for retrying commit or rollback
- * operations on XA resources.
- */
- void setXARetryTimeout(int seconds);
-
- /**
- * Gets the prepared timeout. A transaction branch that is the prepared
- * state waits for an amount of time equal to the prepared timeout before
- * generating a call to <code>replayCompletion</code> on its recovery
- * coordinator.
- *
- * @return the timeout (in seconds) for a transaction branch in the prepared
- * state.
- */
- int getPreparedTimeout();
-
- /**
- * Sets the prepared timeout. A transaction branch that is the prepared
- * state waits for an amount of time equal to the prepared timeout before
- * generating a call to <code>replayCompletion</code> on its recovery
- * coordinator.
- *
- * @param seconds the timeout (in seconds) for a transaction branch in the
- * prepared state.
- */
- void setPreparedTimeout(int seconds);
-
- /**
- * Gets the boolean attribute "root branch remembers heuristic decisions".
- * If this attribute is true, the root branch remembers a heuristically
- * completed transaction until explicitly told (through a call to the MBean
- * operation <code>forget</code>) to forget that transaction. If this
- * attribute is false, the root branch immediately forgets a transaction
- * when the transaction completes.
- *
- * @return true if the root branch remember heuristic decisions,
- * false otherwise.
- */
- boolean isRootBranchRemembersHeuristicDecisions();
-
- /**
- * Sets the boolean attribute "root branch remembers heuristic decisions".
- * If this attribute is true, the root branch remembers a heuristically
- * completed transaction until explicitly told (through a call to the MBean
- * operation <code>forget</code>) to forget that transaction. If this
- * attribute is false, the root branch immediately forgets a transaction
- * when the transaction completes.
- *
- * @param newValue true if the root branch should remember heuristic
- * decisions, false otherwise.
- */
- void setRootBranchRemembersHeuristicDecisions(boolean newValue);
-
- /**
- * Gets the boolean attribute "report heuristic hazard as heuristic mixed".
- * If this attribute is true, each of the commit methods of the JTA API
- * (<code>javax.transaction.Transaction.commit()</code>,
- * <code>javax.transaction.TransactionManager.commit()</code>, and
- * <code>javax.transaction.UserTransaction.commit()</code>) throws a
- * <code>HeuristicMixedException</code> to report a heuristic hazard to its
- * caller. If the attribute is false, those methods do not report heuristic
- * hazards to their callers. In any case, transactions with heuristic hazard
- * status are listed by the MBean operation
- * <code>listHeuristicallyCompletedTransactions()</code>.
- *
- * @return true if a JTA commit throws <code>HeuristicMixedException</code>
- * to report a heuristic hazard to its caller, or false if a JTA
- * commit does not report a heuristic hazard to its caller.
- */
- boolean isReportHeuristicHazardAsHeuristicMixed();
-
- /**
- * Sets the boolean attribute "report heuristic hazard as heuristic mixed".
- * If this attribute is true, each of the commit methods of the JTA API
- * (<code>javax.transaction.Transaction.commit()</code>,
- * <code>javax.transaction.TransactionManager.commit()</code>, and
- * <code>javax.transaction.UserTransaction.commit()</code>) throws a
- * <code>HeuristicMixedException</code> to report a heuristic hazard to its
- * caller. If the attribute is false, those methods do not report heuristic
- * hazards to their callers. In any case, transactions with heuristic hazard
- * status are listed by the MBean operation
- * <code>listHeuristicallyCompletedTransactions()</code>.
- *
- * @param newValue true if a JTA commit should throw
- * <code>HeuristicMixedException</code> to report a heuristic hazard
- * to its caller, or false if a JTA commit should not report a
- * heuristic hazard to its caller.
- */
- void setReportHeuristicHazardAsHeuristicMixed(boolean newValue);
-
- /**
- * mbean get-set pair for field xidFactory Get the value of xidFactory
- * @return value of xidFactory
- */
- ObjectName getXidFactory();
-
- /**
- * Set the value of xidFactory
- * @param xidFactory Value to assign to xidFactory
- */
- void setXidFactory(ObjectName xidFactory);
-
- /**
- * Get the xa terminator
- * @return the xa terminator
- */
- JBossXATerminator getXATerminator();
-
- /**
- * Counts the number of transactions
- * @return the number of active transactions
- */
- long getTransactionCount();
-
- /**
- * The number of commits.
- * @return the number of transactions that have been committed
- */
- long getCommitCount();
-
- /**
- * The number of rollbacks.
- * @return the number of transactions that have been rolled back
- */
- long getRollbackCount();
-
- /**
- * Lists the in-doubt transactions.
- *
- * @return a string with a text listing of in-doubt transactions.
- */
- String listInDoubtTransactions();
-
- /**
- * Heuristically commits an in-doubt transaction.
- *
- * @param localTransactionId the local id of the in-doubt transaction to be
- * heuristically committed.
- */
- void heuristicallyCommit(long localTransactionId);
-
- /**
- * Heuristically commits all in-doubt transactions.
- */
- void heuristicallyCommitAll();
-
- /**
- * Heuristically rolls back an in-doubt transaction.
- *
- * @param localTransactionId the local id of the in-doubt transaction to be
- * heuristically rolled back.
- */
- void heuristicallyRollback(long localTransactionId);
-
- /**
- * Heuristically rolls back all in-doubt transactions.
- */
- void heuristicallyRollbackAll();
-
- /**
- * Lists the heuristically completed transactions coordinated by this
- * transaction manager. A transaction that was heuristically completed
- * by a call to <code>heuristicallyCommit(long localTransactionId)</code>,
- * <code>heuristicallyCommitAll()</code>,
- * <code>heuristicallyRollback(long localTransactionId)</code>, or
- * <code>heuristicallyRollbackAll()</code> does not appear in the listing,
- * as that transaction had a foreign coordinator.
- *
- * @return a string with a text listing of heuristically completed
- * transactions.
- */
- String listHeuristicallyCompletedTransactions();
-
- /**
- * Forgets a heuristically completed transaction coordinated by this
- * transaction manager.
- *
- * @param localTransactionId the local id of a heuristically completed
- * transaction coordinated by this transaction
- * manager.
- */
- void forget(long localTransactionId);
-
- /**
- * Forgets all heuristically completed transactions coordinated by this
- * transaction manager.
- */
- void forgetAll();
-
- /**
- * The <code>registerXAExceptionFormatter</code> method
- * @param clazz a <code>Class</code> value
- * @param formatter a <code>XAExceptionFormatter</code> value
- */
- void registerXAExceptionFormatter(Class clazz, XAExceptionFormatter formatter);
-
- /**
- * The <code>unregisterXAExceptionFormatter</code> method
- * @param clazz a <code>Class</code> value
- */
- void unregisterXAExceptionFormatter(Class clazz);
-
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/TxManager.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/TxManager.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/TxManager.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,1833 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import javax.resource.spi.work.Work;
-import javax.resource.spi.work.WorkCompletedException;
-import javax.resource.spi.work.WorkException;
-import javax.transaction.HeuristicMixedException;
-import javax.transaction.HeuristicRollbackException;
-import javax.transaction.InvalidTransactionException;
-import javax.transaction.NotSupportedException;
-import javax.transaction.RollbackException;
-import javax.transaction.Status;
-import javax.transaction.SystemException;
-import javax.transaction.Transaction;
-import javax.transaction.TransactionManager;
-import javax.transaction.xa.XAException;
-import javax.transaction.xa.Xid;
-
-import org.jboss.logging.Logger;
-import org.jboss.tm.integrity.TransactionIntegrity;
-import org.jboss.tm.recovery.LogRecord;
-import org.jboss.tm.recovery.RecoveryLogger;
-import org.jboss.tm.recovery.TxCompletionHandler;
-import org.jboss.tm.remoting.interfaces.Coordinator;
-import org.jboss.tm.remoting.interfaces.RecoveryCoordinator;
-import org.jboss.tm.remoting.interfaces.Resource;
-import org.jboss.tm.remoting.interfaces.TxPropagationContext;
-import org.jboss.util.UnexpectedThrowable;
-import org.jboss.util.UnreachableStatementException;
-
-/**
- * Our TransactionManager implementation.
- *
- * @author <a href="mailto:rickard.oberg at telkel.com">Rickard Oberg</a>
- * @author <a href="mailto:marc.fleury at telkel.com">Marc Fleury</a>
- * @author <a href="mailto:osh at sparre.dk">Ole Husgaard</a>
- * @author <a href="mailto:jason at planet57.com">Jason Dillon</a>
- * @author <a href="reverbel at ime.usp.br">Francisco Reverbel</a>
- * @author <a href="adrian at jboss.com">Adrian Brock</a>
- * @author <a href="dimitris at jboss.org">Dimitris Andreadis</a>
- * @version $Revision$
- * @deprecated Do not reference directly, use org.jboss.tm.TransactionManagerLocator
- */
-public class TxManager
- implements TransactionManager,
- TransactionPropagationContextImporter,
- TransactionPropagationContextFactory,
- TransactionLocalDelegate,
- TransactionTimeoutConfiguration,
- JBossXATerminator,
- StringRemoteRefConverter
-{
- // Constants -----------------------------------------------------
-
- // Attributes ----------------------------------------------------
-
- /**
- * True if the TxManager should keep a map from GlobalIds to transactions.
- */
- private boolean globalIdsEnabled = false;
-
- /**
- * True if distributed transaction management is enabled.
- */
- private boolean dtmEnabled = false;
-
- /**
- * Whether to interrupt threads at transaction timeout
- */
- private boolean interruptThreads = false;
-
- /**
- * Instance logger.
- */
- private Logger log = Logger.getLogger(this.getClass());
-
- /**
- * True if trace messages should be logged.
- */
- private boolean trace = log.isTraceEnabled();
-
- /**
- * Default timeout in milliseconds.
- * Must be >= 1000!
- */
- private long timeOut = 5 * 60 * 1000;
-
- // The following two fields are ints (not longs) because
- // volatile 64Bit types are broken (i.e. access is not atomic) in most VMs, and we
- // don't want to lock just for a statistic. Additionaly,
- // it will take several years on a highly loaded system to
- // exceed the int range. Note that we might loose an
- // increment every now and then, since the ++ operation is
- // not atomic on volatile data types.
- /**
- * A count of the transactions that have been committed
- */
- private volatile int commitCount;
- /**
- * A count of the transactions that have been rolled back
- */
- private volatile int rollbackCount;
-
- /** The recovery logger */
- private RecoveryLogger recoveryLogger;
-
- /** Indicates that the recovery process was not yet performed */
- private boolean recoveryPending = true;
-
- /** The transaction integrity policy */
- private TransactionIntegrity integrity;
-
- /** Number of completion retries before reporting a heuristic hazard. */
- private int completionRetryLimit = 0; // default: no retries
-
- /** Blocking timeout between completion retries. */
- private int completionRetryTimeout = 1 * 1000; // default: one sec
-
- /** Timeout (in milliseconds) for retrying operations on XA resources */
- private int xaRetryTimeout = 60 * 1000;
-
- /** Timeout (in milliseconds) for a tx branch in the prepared state */
- private int preparedTimeout = 60 * 1000;
-
- /** True if the root branch should remember heuristic decisions */
- private boolean rootBranchRemembersHeuristicDecisions = true;
-
- /** True if heuristic hazards generate JTA heuristic mixed exceptions */
- private boolean reportHeuristicHazardAsHeuristicMixed = false;
-
- // Static --------------------------------------------------------
-
- /**
- * The singleton instance.
- */
- private static TxManager singleton = new TxManager();
-
- /**
- * Get a reference to the singleton instance.
- */
- public static TxManager getInstance()
- {
- return singleton;
- }
-
- // Constructors --------------------------------------------------
-
- /**
- * Private constructor for singleton. Use getInstance() to obtain
- * a reference to the singleton.
- */
- private TxManager()
- {
- //make sure TxCapsule can be used
- TransactionImpl.defaultXidFactory();
- }
-
- // Public --------------------------------------------------------
-
- /**
- * Clears all transactions. <p/>
- * This method exists for testing purposes only. It should not be
- * called during normal operation.
- */
- public void clear()
- {
- Collection txCollection = localIdTx.values();
- synchronized (localIdTx)
- {
- Iterator i = txCollection.iterator();
- while (i.hasNext())
- {
- TransactionImpl tx = (TransactionImpl) i.next();
- tx.deactivate();
- }
- }
- localIdTx.clear();
- if (globalIdsEnabled)
- globalIdTx.clear();
- }
-
- /**
- * Setter for attribute <code>globalIdsEnabled</code>.
- */
- public void setGlobalIdsEnabled(boolean newValue)
- {
- trace = log.isTraceEnabled(); // hack!
- XidImpl.setTrulyGlobalIdsEnabled(newValue);
- globalIdsEnabled = newValue;
- }
-
- /**
- * Getter for attribute <code>globalIdsEnabled</code>.
- */
- public boolean getGlobalIdsEnabled()
- {
- return globalIdsEnabled;
- }
-
- /**
- * Enable/disable thread interruption at transaction timeout.
- *
- * @param interruptThreads pass true to interrupt threads, false otherwise
- */
- public void setInterruptThreads(boolean interruptThreads)
- {
- this.interruptThreads = interruptThreads;
- }
-
- /**
- * Is thread interruption enabled at transaction timeout
- *
- * @return true for interrupt threads, false otherwise
- */
- public boolean isInterruptThreads()
- {
- return interruptThreads;
- }
-
- /**
- * Set the recovery logger
- *
- * @param recoveryLogger the recovery logger
- */
- public void setRecoveryLogger(RecoveryLogger recoveryLogger)
- {
- this.recoveryLogger = recoveryLogger;
- }
-
- /**
- * Get the recovery logger
- *
- * @return the recovery logger
- */
- public RecoveryLogger getRecoveryLogger()
- {
- return recoveryLogger;
- }
-
- /**
- * Clears the recovery pending flag. Called by the recovery manager, at
- * the end of the recovery proccess.
- */
- public void clearRecoveryPending()
- {
- this.recoveryPending = false;
- }
-
- /**
- * Returns the value of the recovery pending flag.
- *
- * @return true is recovery is pending, false otherwise.
- */
- public boolean isRecoveryPending()
- {
- return recoveryPending;
- }
-
- /**
- * Set the transaction integrity policy
- *
- * @param integrity the transaction integrity policy
- */
- public void setTransactionIntegrity(TransactionIntegrity integrity)
- {
- this.integrity = integrity;
- }
-
- /**
- * Get the transaction integrity policy
- *
- * @return the transaction integrity policy
- */
- public TransactionIntegrity getTransactionIntegrity()
- {
- return integrity;
- }
-
- /**
- * Sets the completion retry limit. This is the maximum number of times that
- * the transaction manager retries a completion operation (either commit or
- * rollback) on a resource (either a remote <code>Resource</code> or an
- * <code>XAResource</code>) that raised a transient exception. Whoever called
- * the transaction manager is blocked while the completion retries are
- * performed. If the completion retry limit is reached, the transaction
- * manager abandons the retries and throws a heuristic hazard exception.
- *
- * @param maxCompletionRetries the completion retry limit.
- */
- public void setCompletionRetryLimit(int maxCompletionRetries)
- {
- this.completionRetryLimit = maxCompletionRetries;
- }
-
- /**
- * Gets the completion retry limit. This is the maximum number of times that
- * the transaction manager retries a completion operation (either commit or
- * rollback) on a resource (either a remote <code>Resource</code> or an
- * <code>XAResource</code>) that raised a transient exception. Whoever called
- * the transaction manager is blocked while the completion retries are
- * performed. If the completion retry limit is reached, the transaction
- * manager abandons the retries and throws a heuristic hazard exception.
- *
- * @return the completion retry limit.
- */
- public int getCompletionRetryLimit()
- {
- return completionRetryLimit;
- }
-
- /**
- * Sets the completion retry timeout. The completion retry timeout is the
- * number of seconds that the transaction manager waits before retrying a
- * completion operation (either commit or rollback) on a resource (either a
- * remote <code>Resource</code> or an <code>XAResource</code>) that raised a
- * transient exception. This is a blocking timeout (whoever called the
- * transaction manager is blocked until the commit or rollback is retried)
- * and is applicable if the transaction manager did not report a heuristic
- * hazard for the transaction. If a heuristic hazard has been reported, then
- * the applicable timouts are the non-blocking ones: the XA retry timeout and
- * the prepared timeout.
- *
- * @param seconds the timeout (in seconds) for retrying a completion
- * operation after a transient exception and before the
- * transaction manager reports a heuristic hazard.
- */
- public void setCompletionRetryTimeout(int seconds)
- {
- this.completionRetryTimeout = 1000 * seconds;
- }
-
- /**
- * Gets the completion retry timeout. The completion retry timeout is the
- * number of seconds that the transaction manager waits before retrying a
- * completion operation (either commit or rollback) on a resource (either a
- * remote <code>Resource</code> or an <code>XAResource</code>) that raised a
- * transient exception. This is a blocking timeout (whoever called the
- * transaction manager is blocked until the commit or rollback is retried)
- * and is applicable if the transaction manager did not report a heuristic
- * hazard for the transaction. If a heuristic hazard has been reported, then
- * the applicable timouts are the non-blocking ones: the XA retry timeout and
- * the prepared timeout.
- *
- * @return the timeout (in seconds) for retrying a completion operation
- * after a transient exception and before the transaction manager
- * reports a heuristic hazard.
- */
- public int getCompletionRetryTimeout()
- {
- return completionRetryTimeout / 1000;
- }
-
- /**
- * Gets the completion retry timeout in milliseconds.
- *
- * @return the timeout (in milliseconds) for retrying a completion operation
- * after a transient exception and before the transaction manager
- * reports a heuristic hazard.
- */
- public int getCompletionRetryTimeoutMillis()
- {
- return xaRetryTimeout;
- }
-
- /**
- * Sets the XA retry timeout.
- *
- * @param seconds the timeout (in seconds) for retrying operations on XA
- * resources.
- */
- public void setXARetryTimeout(int seconds)
- {
- this.xaRetryTimeout = 1000 * seconds;
- }
-
- /**
- * Gets the XA retry timeout.
- *
- * @return the timeout (in seconds) for retrying operations on XA resources.
- */
- public int getXARetryTimeout()
- {
- return xaRetryTimeout / 1000;
- }
-
- /**
- * Gets the XA retry timeout in milliseconds.
- *
- * @return the timeout (in milliseconds) for retrying operations on XA
- * resources.
- */
- public int getXARetryTimeoutMillis()
- {
- return xaRetryTimeout;
- }
-
- /**
- * Sets the prepared timeout. A transaction branch that is the prepared
- * state waits for an amount of time equal to the prepared timeout before
- * generating a call to <code>replayCompletion</code> on its recovery
- * coordinator.
- *
- * @param seconds the timeout (in seconds) for a transaction branch in the
- * the prepared state.
- */
- public void setPreparedTimeout(int seconds)
- {
- this.preparedTimeout = 1000 * seconds;
- }
-
- /**
- * Gets the prepared timeout. A transaction branch that is the prepared
- * state waits for an amount of time equal to the prepared timeout before
- * generating a call to <code>replayCompletion</code> on its recovery
- * coordinator.
- *
- * @return the timeout (in seconds) for a transaction branch in the prepared
- * state.
- */
- public int getPreparedTimeout()
- {
- return preparedTimeout / 1000;
- }
-
- /**
- * Gets the prepared timeout in milliseconds.
- *
- * @return the timeout (in milliseconds) for a transaction branch in the
- * prepared state.
- */
- public int getPreparedTimeoutMillis()
- {
- return preparedTimeout;
- }
-
- /**
- * Sets the boolean attribute "root branch remembers heuristic decisions".
- * If this attribute is true, the root branch remembers a heuristically
- * completed transaction until explicitly told (through a call to the MBean
- * operation <code>forget</code>) to forget that transaction. If this
- * attribute is false, the root branch immediately forgets a transaction
- * when the transaction completes.
- *
- * @param newValue true if the root branch should remember heuristic
- * decisions, false otherwise.
- */
- public void setRootBranchRemembersHeuristicDecisions(boolean newValue)
- {
- rootBranchRemembersHeuristicDecisions = newValue;
- }
-
- /**
- * Gets the boolean attribute "root branch remembers heuristic decisions".
- * If this attribute is true, the root branch remembers a heuristically
- * completed transaction until explicitly told (through a call to the MBean
- * operation <code>forget</code>) to forget that transaction. If this
- * attribute is false, the root branch immediately forgets a transaction
- * when the transaction completes.
- *
- * @return true if the root branch remember heuristic decisions,
- * false otherwise.
- */
- public boolean isRootBranchRemembersHeuristicDecisions()
- {
- return rootBranchRemembersHeuristicDecisions;
- }
-
- /**
- * Sets the boolean attribute "report heuristic hazard as heuristic mixed".
- * If this attribute is true, each of the commit methods of the JTA API
- * (<code>javax.transaction.Transaction.commit()</code>,
- * <code>javax.transaction.TransactionManager.commit()</code>, and
- * <code>javax.transaction.UserTransaction.commit()</code>) throws a
- * <code>HeuristicMixedException</code> to report a heuristic hazard to its
- * caller. If the attribute is false, those methods do not report heuristic
- * hazards to their callers. In any case, transactions with heuristic hazard
- * status are listed by the MBean operation
- * <code>listHeuristicallyCompletedTransactions()</code>.
- *
- * @param newValue true if a JTA commit should throw
- * <code>HeuristicMixedException</code> to report a heuristic hazard
- * to its caller, or false if a JTA commit should not report a
- * heuristic hazard to its caller.
- */
- public void setReportHeuristicHazardAsHeuristicMixed(boolean newValue)
- {
- reportHeuristicHazardAsHeuristicMixed = newValue;
- }
-
- /**
- * Gets the boolean attribute "report heuristic hazard as heuristic mixed".
- * If this attribute is true, each of the commit methods of the JTA API
- * (<code>javax.transaction.Transaction.commit()</code>,
- * <code>javax.transaction.TransactionManager.commit()</code>, and
- * <code>javax.transaction.UserTransaction.commit()</code>) throws a
- * <code>HeuristicMixedException</code> to report a heuristic hazard to its
- * caller. If the attribute is false, those methods do not report heuristic
- * hazards to their callers. In any case, transactions with heuristic hazard
- * status are listed by the MBean operation
- * <code>listHeuristicallyCompletedTransactions()</code>.
- *
- * @return true if a JTA commit throws <code>HeuristicMixedException</code>
- * to report a heuristic hazard to its caller, or false if a JTA
- * commit does not report a heuristic hazard to its caller.
- */
- public boolean isReportHeuristicHazardAsHeuristicMixed()
- {
- return reportHeuristicHazardAsHeuristicMixed;
- }
-
- /**
- * Begin a new transaction.
- * The new transaction will be associated with the calling thread.
- */
- public void begin()
- throws NotSupportedException,
- SystemException
- {
- trace = log.isTraceEnabled(); // hack!
-
- ThreadInfo ti = getThreadInfo();
- TransactionImpl current = ti.tx;
-
- if (current != null)
- {
- if (current.isDone())
- disassociateThread(ti);
- else
- throw new NotSupportedException
- ("Transaction already active, cannot nest transactions.");
- }
-
- long timeout = (ti.timeout == 0) ? timeOut : ti.timeout;
- TransactionImpl tx = new TransactionImpl(timeout);
- associateThread(ti, tx);
- localIdTx.put(tx.getLocalId(), tx);
- if (globalIdsEnabled)
- globalIdTx.put(tx.getGlobalId(), tx);
-
- if (trace)
- log.trace("began tx: " + tx);
- }
-
- /**
- * Commit the transaction associated with the currently running thread.
- */
- public void commit()
- throws RollbackException,
- HeuristicMixedException,
- HeuristicRollbackException,
- SecurityException,
- IllegalStateException,
- SystemException
- {
- ThreadInfo ti = getThreadInfo();
- TransactionImpl current = ti.tx;
-
- if (current != null)
- {
- current.commit();
- disassociateThread(ti);
- if (trace)
- log.trace("commited tx: " + current);
- }
- else
- throw new IllegalStateException("No transaction.");
- }
-
- /**
- * Return the status of the transaction associated with the currently
- * running thread, or <code>Status.STATUS_NO_TRANSACTION</code> if no
- * active transaction is currently associated.
- */
- public int getStatus()
- throws SystemException
- {
- ThreadInfo ti = getThreadInfo();
- TransactionImpl current = ti.tx;
-
- if (current != null)
- {
- if (current.isDone())
- disassociateThread(ti);
- else
- return current.getStatus();
- }
- return Status.STATUS_NO_TRANSACTION;
- }
-
- /**
- * Return the transaction currently associated with the invoking thread,
- * or <code>null</code> if no active transaction is currently associated.
- */
- public Transaction getTransaction()
- throws SystemException
- {
- ThreadInfo ti = getThreadInfo();
- TransactionImpl current = ti.tx;
-
- if (current != null && current.isDone())
- {
- current = null;
- disassociateThread(ti);
- }
-
- return current;
- }
-
- /**
- * Resume a transaction.
- * <p/>
- * Note: This will not enlist any resources involved in this
- * transaction. According to JTA1.0.1 specification section 3.2.3,
- * that is the responsibility of the application server.
- */
- public void resume(Transaction transaction)
- throws InvalidTransactionException,
- IllegalStateException,
- SystemException
- {
- if (transaction != null && !(transaction instanceof TransactionImpl))
- throw new RuntimeException("Not a TransactionImpl, but a " +
- transaction.getClass().getName());
-
- ThreadInfo ti = getThreadInfo();
- TransactionImpl current = ti.tx;
-
- if (current != null)
- {
- if (current.isDone())
- current = ti.tx = null;
- else
- throw new IllegalStateException("Already associated with a tx");
- }
-
- if (current != transaction)
- {
- associateThread(ti, (TransactionImpl) transaction);
- }
-
- if (trace)
- log.trace("resumed tx: " + ti.tx);
- }
-
- /**
- * Suspend the transaction currently associated with the current
- * thread, and return it.
- * <p/>
- * Note: This will not delist any resources involved in this
- * transaction. According to JTA1.0.1 specification section 3.2.3,
- * that is the responsibility of the application server.
- */
- public Transaction suspend()
- throws SystemException
- {
- ThreadInfo ti = getThreadInfo();
- TransactionImpl current = ti.tx;
-
- if (current != null)
- {
- current.disassociateCurrentThread();
- ti.tx = null;
-
- if (trace)
- log.trace("suspended tx: " + current);
-
- if (current.isDone())
- current = null;
- }
-
- return current;
- }
-
- /**
- * Roll back the transaction associated with the currently running thread.
- */
- public void rollback()
- throws IllegalStateException,
- SecurityException,
- SystemException
- {
- ThreadInfo ti = getThreadInfo();
- TransactionImpl current = ti.tx;
-
- if (current != null)
- {
- if (!current.isDone())
- {
- current.rollback();
-
- if (trace)
- log.trace("rolled back tx: " + current);
- return;
- }
- disassociateThread(ti);
- }
- throw new IllegalStateException("No transaction.");
- }
-
- /**
- * Mark the transaction associated with the currently running thread
- * so that the only possible outcome is a rollback.
- */
- public void setRollbackOnly()
- throws IllegalStateException,
- SystemException
- {
- ThreadInfo ti = getThreadInfo();
- TransactionImpl current = ti.tx;
-
- if (current != null)
- {
- if (!current.isDone())
- {
- current.setRollbackOnly();
-
- if (trace)
- log.trace("tx marked for rollback only: " + current);
- return;
- }
- ti.tx = null;
- }
- throw new IllegalStateException("No transaction.");
- }
-
- public int getTransactionTimeout()
- {
- return (int) (getThreadInfo().timeout / 1000);
- }
-
- /**
- * Set the transaction timeout for new transactions started by the
- * calling thread.
- */
- public void setTransactionTimeout(int seconds)
- throws SystemException
- {
- getThreadInfo().timeout = 1000 * seconds;
-
- if (trace)
- log.trace("tx timeout is now: " + seconds + "s");
- }
-
- /**
- * Set the default transaction timeout for new transactions.
- * This default value is used if <code>setTransactionTimeout()</code>
- * was never called, or if it was called with a value of <code>0</code>.
- */
- public void setDefaultTransactionTimeout(int seconds)
- {
- timeOut = 1000L * seconds;
-
- if (trace)
- log.trace("default tx timeout is now: " + seconds + "s");
- }
-
- /**
- * Get the default transaction timeout.
- *
- * @return Default transaction timeout in seconds.
- */
- public int getDefaultTransactionTimeout()
- {
- return (int) (timeOut / 1000);
- }
-
- public long getTimeLeftBeforeTransactionTimeout(boolean errorRollback) throws RollbackException
- {
- try
- {
- ThreadInfo ti = getThreadInfo();
- TransactionImpl current = ti.tx;
- if (current != null && current.isDone())
- {
- disassociateThread(ti);
- return -1;
- }
- return current.getTimeLeftBeforeTimeout(errorRollback);
- }
- catch (RollbackException e)
- {
- throw e;
- }
- catch (Exception ignored)
- {
- return -1;
- }
- }
-
- /**
- * The following 2 methods are here to provide association and
- * disassociation of the thread.
- */
- public Transaction disassociateThread()
- {
- return disassociateThread(getThreadInfo());
- }
-
- private Transaction disassociateThread(ThreadInfo ti)
- {
- TransactionImpl current = ti.tx;
- ti.tx = null;
- current.disassociateCurrentThread();
- return current;
- }
-
- public void associateThread(Transaction transaction)
- {
- if (transaction != null && !(transaction instanceof TransactionImpl))
- throw new RuntimeException("Not a TransactionImpl, but a " +
- transaction.getClass().getName());
-
- // Associate with the thread
- TransactionImpl transactionImpl = (TransactionImpl) transaction;
- ThreadInfo ti = getThreadInfo();
- ti.tx = transactionImpl;
- transactionImpl.associateCurrentThread();
- }
-
- private void associateThread(ThreadInfo ti, TransactionImpl transaction)
- {
- // Associate with the thread
- ti.tx = transaction;
- transaction.associateCurrentThread();
- }
-
- /**
- * Return the number of active transactions
- */
- public int getTransactionCount()
- {
- return localIdTx.size();
- }
-
- /**
- * A count of the transactions that have been committed
- */
- public long getCommitCount()
- {
- return commitCount;
- }
-
- /**
- * A count of the transactions that have been rolled back
- */
- public long getRollbackCount()
- {
- return rollbackCount;
- }
-
- /**
- * Lists the in-doubt transactions.
- *
- * @return a string with a text listing of in-doubt transactions.
- */
- public String listInDoubtTransactions()
- {
- // TODO
- throw new org.jboss.util.NotImplementedException();
- }
-
- /**
- * Heuristically commits an in-doubt transaction.
- *
- * @param localTransactionId the local id of the in-doubt transaction to be
- * heuristically committed.
- */
- public void heuristicallyCommit(long localTransactionId)
- {
- // TODO
- throw new org.jboss.util.NotImplementedException();
- }
-
- /**
- * Heuristically commits all in-doubt transactions.
- */
- public void heuristicallyCommitAll()
- {
- // TODO
- throw new org.jboss.util.NotImplementedException();
- }
-
- /**
- * Heuristically rolls back an in-doubt transaction.
- *
- * @param localTransactionId the local id of the in-doubt transaction to be
- * heuristically rolled back.
- */
- public void heuristicallyRollback(long localTransactionId)
- {
- // TODO
- throw new org.jboss.util.NotImplementedException();
- }
-
- /**
- * Heuristically rolls back all in-doubt transactions.
- */
- public void heuristicallyRollbackAll()
- {
- // TODO
- throw new org.jboss.util.NotImplementedException();
- }
-
- /**
- * Lists the heuristically completed transactions coordinated by this
- * transaction manager. A transaction that was heuristically completed
- * by a call to <code>heuristicallyCommit(long localTransactionId)</code>,
- * <code>heuristicallyCommitAll()</code>,
- * <code>heuristicallyRollback(long localTransactionId)</code>, or
- * <code>heuristicallyRollbackAll()</code> does not appear in the listing,
- * as that transaction had a foreign coordinator.
- *
- * @return a string with a text listing of heuristically completed
- * transactions.
- */
- public String listHeuristicallyCompletedTransactions()
- {
- // TODO
- throw new org.jboss.util.NotImplementedException();
- }
-
- /**
- * Forgets a heuristically completed transaction coordinated by this
- * transaction manager.
- *
- * @param localTransactionId the local id of a heuristically completed
- * transaction coordinated by this transaction
- * manager.
- */
- public void forget(long localTransactionId)
- {
- // TODO
- throw new org.jboss.util.NotImplementedException();
- }
-
- /**
- * Forgets all heuristically completed transactions coordinated by this
- * transaction manager.
- */
- public void forgetAll()
- {
- // TODO
- throw new org.jboss.util.NotImplementedException();
- }
-
- // Implements TransactionPropagationContextImporter ---------------
-
- /**
- * Import a transaction propagation context into this TM.
- * The TPC is loosely typed, as we may (at a later time) want to
- * import TPCs that come from other transaction domains without
- * offloading the conversion to the client.
- *
- * @param tpc The transaction propagation context that we want to
- * import into this TM. Currently this is an instance
- * of LocalId. At some later time this may be an instance
- * of a transaction propagation context from another
- * transaction domain like
- * org.omg.CosTransactions.PropagationContext.
- * @return a transaction representing this transaction propagation
- * context, or null if this TPC cannot be imported.
- */
- public Transaction importTransactionPropagationContext(Object tpc)
- {
- if (tpc instanceof LocalId)
- {
- LocalId id = (LocalId) tpc;
- return (Transaction) localIdTx.get(id);
- }
- else if (tpc instanceof GlobalId && globalIdsEnabled)
- {
- GlobalId id = (GlobalId) tpc;
- Transaction tx = (Transaction) globalIdTx.get(id);
- if (trace)
- {
- if (tx != null)
- log.trace("Successfully imported transaction context " + tpc);
- else
- log.trace("Could not import transaction context " + tpc);
- }
- return tx;
- }
- else if (tpc instanceof TxPropagationContext && dtmEnabled)
- {
- TxPropagationContext fullTpc = (TxPropagationContext) tpc;
- Transaction tx = importExternalTransaction(fullTpc.formatId,
- fullTpc.globalId,
- fullTpc.coordinator,
- fullTpc.timeout * 1000);
- if (trace)
- {
- if (tx != null)
- log.trace("Successfully imported transaction context " + tpc);
- else
- log.trace("Could not import transaction context " + tpc);
- }
- return tx;
- }
- log.warn("Cannot import transaction propagation context: " + tpc);
- return null;
- }
-
- // Implements TransactionPropagationContextFactory ---------------
-
- /**
- * Return a TPC for the current transaction.
- */
- public Object getTransactionPropagationContext()
- {
- return getTransactionPropagationContext(getThreadInfo().tx);
- }
-
- /**
- * Return a TPC for the argument transaction.
- */
- public Object getTransactionPropagationContext(Transaction t)
- {
- // If no transaction or unknown transaction class, return null.
- if (t == null)
- return null;
- if (!(t instanceof TransactionImpl))
- {
- log.warn("Cannot export transaction propagation context: " + t);
- return null;
- }
-
- TransactionImpl tx = (TransactionImpl) t;
-
- if (!dtmEnabled)
- {
- return tx.getLocalId();
- }
- else
- {
- return tx.getPropagationContext();
- }
- }
-
- // Implements XATerminator ----------------------------------
-
- public void registerWork(Work work, Xid xid, long timeout)
- throws WorkCompletedException
- {
- if (trace)
- log.trace("registering work=" + work + " xid=" + xid +
- " timeout=" + timeout);
- try
- {
- TransactionImpl tx = importExternalTransaction(xid, timeout);
- tx.setWork(work);
- }
- catch (WorkCompletedException e)
- {
- throw e;
- }
- catch (Throwable t)
- {
- WorkCompletedException e =
- new WorkCompletedException("Error registering work", t);
- e.setErrorCode(WorkException.TX_RECREATE_FAILED);
- throw e;
- }
- if (trace)
- log.trace("registered work= " + work + " xid=" + xid +
- " timeout=" + timeout);
- }
-
- public void startWork(Work work, Xid xid)
- throws WorkCompletedException
- {
- if (trace)
- log.trace("starting work=" + work + " xid=" + xid);
- TransactionImpl tx = getExternalTransaction(xid);
- associateThread(tx);
- if (trace)
- log.trace("started work= " + work + " xid=" + xid);
- }
-
- public void endWork(Work work, Xid xid)
- {
- if (trace)
- log.trace("ending work=" + work + " xid=" + xid);
- try
- {
- TransactionImpl tx = getExternalTransaction(xid);
- tx.setWork(null);
- disassociateThread();
- }
- catch (WorkCompletedException e)
- {
- log.error("Unexpected error from endWork ", e);
- throw new UnexpectedThrowable(e.toString());
- }
- if (trace)
- log.trace("ended work=" + work + " xid=" + xid);
- }
-
- public void cancelWork(Work work, Xid xid)
- {
- if (trace)
- log.trace("cancling work=" + work + " xid=" + xid);
- try
- {
- TransactionImpl tx = getExternalTransaction(xid);
- tx.setWork(null);
- }
- catch (WorkCompletedException e)
- {
- log.error("Unexpected error from cancelWork ", e);
- throw new UnexpectedThrowable(e.toString());
- }
- if (trace)
- log.trace("cancled work=" + work + " xid=" + xid);
- }
-
- public int prepare(Xid xid)
- throws XAException
- {
- if (trace)
- log.trace("preparing xid=" + xid);
- try
- {
- TransactionImpl tx = getExternalTransaction(xid);
- resume(tx);
- int result = tx.prepare(xid);
- if (trace)
- log.trace("prepared xid=" + xid + " result=" + result);
- return result;
- }
- catch (Throwable t)
- {
- JBossXAException.rethrowAsXAException("Error during prepare", t);
- throw new UnreachableStatementException();
- }
- finally
- {
- try
- {
- suspend();
- }
- catch (SystemException e)
- {
- JBossXAException.rethrowAsXAException("Error during prepare", e);
- throw new UnreachableStatementException();
- }
- }
- }
-
- public void rollback(Xid xid)
- throws XAException
- {
- if (trace)
- log.trace("rolling back xid=" + xid);
- try
- {
- TransactionImpl tx = getExternalTransaction(xid);
- tx.rollback();
- }
- catch (Throwable t)
- {
- JBossXAException.rethrowAsXAException("Error during rollback", t);
- }
- if (trace)
- log.trace("rolled back xid=" + xid);
- }
-
- public void commit(Xid xid, boolean onePhase)
- throws XAException
- {
- if (trace)
- log.trace("committing xid=" + xid + " onePhase=" + onePhase);
- try
- {
- TransactionImpl tx = getExternalTransaction(xid);
- tx.commit(onePhase);
- }
- catch (Throwable t)
- {
- JBossXAException.rethrowAsXAException("Error during commit", t);
- }
- if (trace)
- log.trace("committed xid=" + xid);
- }
-
- public void forget(Xid xid)
- throws XAException
- {
- if (trace)
- log.trace("forgetting xid=" + xid);
- try
- {
- TransactionImpl tx = getExternalTransaction(xid);
- tx.forget();
- }
- catch (Throwable t)
- {
- JBossXAException.rethrowAsXAException("Error during forget", t);
- }
- if (trace)
- log.trace("forgot xid=" + xid);
- }
-
- public Xid[] recover(int flag)
- throws XAException
- {
- List xidList = new ArrayList();
- Collection txCollection = localIdTx.values();
- synchronized (localIdTx)
- {
- Iterator i = txCollection.iterator();
- while (i.hasNext())
- {
- TransactionImpl tx = (TransactionImpl) i.next();
- if (tx.isPreparedOrHeuristicallyCompletedJCAInboundTx())
- xidList.add(tx.getInboundXid());
- }
- }
- return (Xid[]) xidList.toArray(new Xid[xidList.size()]);
- }
-
- /**
- * Imports an external transaction. This method is called for foreign
- * transaction imported through DTM or OTS transaction propagation contexts.
- */
- public TransactionImpl importExternalTransaction(int formatId,
- byte[] globalId,
- Coordinator coordinator,
- long txTimeOut)
- {
- GlobalId gid = new GlobalId(formatId, globalId);
- TransactionImpl tx = (TransactionImpl) globalIdTx.get(gid);
- if (tx != null)
- {
- if (trace)
- log.trace("imported existing transaction gid: " + gid +
- " tx=" + tx);
- }
- else
- {
- ThreadInfo ti = getThreadInfo();
- long timeout = (ti.timeout == 0) ? txTimeOut : ti.timeout;
- tx = new TransactionImpl(gid, coordinator, timeout);
- localIdTx.put(tx.getLocalId(), tx);
- if (globalIdsEnabled)
- globalIdTx.put(gid, tx);
-
- if (trace)
- log.trace("imported new transaction gid: " + gid + " tx=" + tx +
- " timeout=" + timeout);
- }
- return tx;
- }
-
- /**
- * Imports an external transaction. This method is called for foreign
- * transactions imported through the JCA transaction inflow mechanism.
- */
- TransactionImpl importExternalTransaction(Xid xid, long txTimeOut)
- {
- GlobalId gid = new GlobalId(xid.getFormatId(),
- xid.getGlobalTransactionId());
- TransactionImpl tx = (TransactionImpl) globalIdTx.get(gid);
- if (tx != null)
- {
- if (trace)
- log.trace("imported existing transaction gid: " + gid +
- " tx=" + tx);
- }
- else
- {
- ThreadInfo ti = getThreadInfo();
- long timeout = (ti.timeout == 0) ? txTimeOut : ti.timeout;
- tx = new TransactionImpl(gid, xid.getBranchQualifier(), timeout);
- localIdTx.put(tx.getLocalId(), tx);
- if (globalIdsEnabled)
- globalIdTx.put(gid, tx);
-
- if (trace)
- log.trace("imported new transaction gid: " + gid + " tx=" + tx +
- " timeout=" + timeout);
- }
- return tx;
- }
-
- TransactionImpl getExternalTransaction(Xid xid)
- throws WorkCompletedException
- {
- GlobalId gid = new GlobalId(xid);
- TransactionImpl tx = (TransactionImpl) globalIdTx.get(gid);
- if (tx == null)
- throw new WorkCompletedException("Xid not found " + xid,
- WorkException.TX_RECREATE_FAILED);
- return tx;
- }
-
- /**
- * Recreates a locally-started transaction that does not involve other
- * transaction managers. This method is intended to be called at recovery
- * time, for recreating transactions that were in the committing state when
- * the server crashed. Such a transaction completed the first phase of the
- * 2PC protocol and logged the commit decision, but it must still send
- * commit messages to some or all of its <code>XAResource</code>s.
- *
- * @param localId the local id of a locally-started transaction that is in
- * the committing state and does not involve other transaction
- * managers
- * @param pendingXAWorkList a list of <code>org.jboss.tm.XAWork</code>
- * instances containing one element for each
- * <code>XAResource</code> that is enlisted with the transaction
- * and is still in the prepared state
- * @param completionHandler the
- * <code>org.jboss.tm.recovery.TxCompletionHandler</code> to be
- * notifed when the second phase of the 2PC completes
- * @param heurData either null or a <code>LogRecord.HeurData</code> instance
- * contaning information on a locally-detected heuristic hazard.
- */
- public void recreateTransaction(long localId,
- List pendingXAWorkList,
- TxCompletionHandler completionHandler,
- LogRecord.HeurData heurData)
- {
- LocalId localIdObject = new LocalId(localId);
- TransactionImpl tx = (TransactionImpl) localIdTx.get(localIdObject);
- if (tx != null)
- {
- if (trace)
- log.trace("recreateTransaction called for existing transaction, " +
- "localId=" + localId + ", tx=" + tx,
- new Throwable("[Stack trace]"));
- }
- else
- {
- tx = new TransactionImpl(localId,
- pendingXAWorkList,
- completionHandler,
- heurData);
- localIdTx.put(tx.getLocalId(), tx);
- if (globalIdsEnabled)
- globalIdTx.put(tx.getGlobalId(), tx);
-
- if (trace)
- log.trace("recreated transaction with localId=" + localId +
- ", tx=" + tx +
- ", status=" + TxUtils.getStatusAsString(tx.getStatus()));
- }
- }
-
- /**
- * Recreates a locally-started transaction that involves other transaction
- * managers. Involving other transaction managers means that there are
- * remote <code>Resource</code>s enlisted with the transaction. This method
- * is intended to be called at recovery time, for recreating transactions
- * that were in the committing state when the server crashed. Such a
- * transaction completed the first phase of the 2PC protocol and logged the
- * commit decision, but it must still send commit messages to some or all of
- * its resources (<code>XAResource</code>s and remote
- * <code>Resource</code>s).
- *
- * @param localId the local id of a locally-started transaction that is in
- * the committing state and involves other transaction managers
- * @param pendingXAWorkList a list of <code>org.jboss.tm.XAWork</code>
- * instances containing one element for each
- * <code>XAResource</code> that is enlisted with the transaction
- * and is still in the prepared state
- * @param resources an array with stringfied references for the remote
- * <code>Resource</code>s enlisted with the transaction
- * @param completionHandler the
- * <code>org.jboss.tm.recovery.TxCompletionHandler</code> to be
- * notifed when the second phase of the 2PC completes
- * @param heurData either null or a <code>LogRecord.HeurData</code> instance
- * contaning information on a locally-detected heuristic hazard.
- */
- public void recreateTransaction(long localId,
- List pendingXAWorkList,
- String[] resources,
- TxCompletionHandler completionHandler,
- LogRecord.HeurData heurData)
- {
- LocalId localIdObject = new LocalId(localId);
- TransactionImpl tx = (TransactionImpl) localIdTx.get(localIdObject);
- if (tx != null)
- {
- if (trace)
- log.trace("recreateTransaction called for existing transaction, " +
- "localId=" + localId + ", tx=" + tx,
- new Throwable("[Stack trace]"));
- }
- else
- {
- tx = new TransactionImpl(localId,
- pendingXAWorkList,
- resources,
- completionHandler,
- heurData);
- localIdTx.put(tx.getLocalId(), tx);
- if (globalIdsEnabled)
- globalIdTx.put(tx.getGlobalId(), tx);
-
- if (trace)
- log.trace("recreated transaction with localId=" + localId +
- ", tx=" + tx +
- ", status=" + TxUtils.getStatusAsString(tx.getStatus()));
- }
- }
-
- /**
- * Recreates a foreign transaction that entered this virtual machine in a
- * transaction context propagated along with a remote method invocation.
- * This method is intended to be called at recovery time, for recreating
- * transactions that were in the prepared state when the server crashed.
- *
- * @param localId the local id of a foreign transaction that entered this
- * virtual machine in a transaction propagation context and is
- * propagated along with a remote method invocation and is in
- * the prepared state
- * @param inboundFormatId format id part of the foreign transaction
- * identifier that entered this virtual machine
- * @param globalTransactionId global id part of the foreign transaction
- * identifier that entered this virtual machine
- * @param recoveryCoord an stringfied reference to the transaction branch's
- * <code>RecovertyCoordinator</code>
- * @param pendingXAWorkList a list of <code>org.jboss.tm.XAWork</code>
- * instances containing one element for each
- * <code>XAResource</code> enlisted with the transaction
- * @param resources an array with stringfied references for the remote
- * <code>Resource</code>s enlisted with the transaction
- * @param completionHandler the
- * <code>org.jboss.tm.recovery.TxCompletionHandler</code> to be
- * notifed when the second phase of the 2PC completes
- * @param heurData either null or a <code>LogRecord.HeurData</code> instance
- * contaning information on a locally-detected heuristic hazard.
- */
- public void recreateTransaction(long localId,
- int inboundFormatId,
- byte[] globalTransactionId,
- String recoveryCoord,
- List pendingXAWorkList,
- String[] resources,
- TxCompletionHandler completionHandler,
- LogRecord.HeurData heurData)
- {
- LocalId localIdObject = new LocalId(localId);
- TransactionImpl tx = (TransactionImpl) localIdTx.get(localIdObject);
- if (tx != null)
- {
- if (trace)
- log.trace("recreateTransaction called for existing transaction, " +
- "localId=" + localId + ", tx=" + tx,
- new Throwable("[Stack trace]"));
- }
- else
- {
- tx = new TransactionImpl(localId,
- inboundFormatId,
- globalTransactionId,
- recoveryCoord,
- pendingXAWorkList,
- resources,
- completionHandler,
- heurData);
- localIdTx.put(tx.getLocalId(), tx);
- if (globalIdsEnabled)
- globalIdTx.put(tx.getGlobalId(), tx);
-
- if (trace)
- log.trace("recreated transaction with localId=" + localId +
- " tx=" + tx +
- ", status=" + TxUtils.getStatusAsString(tx.getStatus()));
- }
- }
-
- /**
- * Recreates a foreign transaction that entered this virtual machine through
- * JCA transaction inflow. This method is intended to be called at recovery
- * time, for recreating transactions that were in the prepared state when
- * the server crashed.
- *
- * @param localId the local id of a foreign transaction that entered this
- * virtual machine in a transaction propagation context and is
- * propagated along with a remote method invocation and is in
- * the prepared state
- * @param inboundFormatId format id part of the foreign <code>Xid</code>
- * @param globalTransactionId global id part of the foreign <code>Xid</code>
- * @param inboundBranchQualifier the branch qualifier part of the foreign
- * <code>Xid</code>
- * @param pendingXAWorkList a list of <code>org.jboss.tm.XAWork</code>
- * instances containing one element for each
- * <code>XAResource</code> enlisted with the transaction
- * @param resources an array with stringfied references for the remote
- * <code>Resource</code>s enlisted with the transaction
- * @param completionHandler the
- * <code>org.jboss.tm.recovery.TxCompletionHandler</code> to be
- * notifed when the second phase of the 2PC completes
- * @param heurData either null or a <code>LogRecord.HeurData</code> instance
- * contaning information on a locally-detected heuristic hazard.
- */
- public void recreateTransaction(long localId,
- int inboundFormatId,
- byte[] globalTransactionId,
- byte[] inboundBranchQualifier,
- List pendingXAWorkList,
- String[] resources,
- TxCompletionHandler completionHandler,
- LogRecord.HeurData heurData)
- {
- LocalId localIdObject = new LocalId(localId);
- TransactionImpl tx = (TransactionImpl) localIdTx.get(localIdObject);
- if (tx != null)
- {
- if (trace)
- log.trace("recreateTransaction called for existing transaction, " +
- "localId=" + localId + ", tx=" + tx,
- new Throwable("[Stack trace]"));
- }
- else
- {
- tx = new TransactionImpl(localId,
- inboundFormatId,
- globalTransactionId,
- inboundBranchQualifier,
- pendingXAWorkList,
- resources,
- completionHandler,
- heurData);
- localIdTx.put(tx.getLocalId(), tx);
- if (globalIdsEnabled)
- globalIdTx.put(tx.getGlobalId(), tx);
-
- if (trace)
- log.trace("recreated transaction with localId=" + localId +
- ", tx=" + tx +
- ", status=" + TxUtils.getStatusAsString(tx.getStatus()));
- }
- }
-
- /**
- * Recreates a transaction that is in a heuristically completed state
- * (either committed or rolledback). This method is intended to be called
- * at recovery time, for recreating heuristically completed transactions
- * that were not yet forgotten when the server crashed.
- *
- * @param heurData an instance of <code>LogRecord.HeurData</code> with
- * information on the heuristically completed transaction
- * @param xaResourcesWithHeuristics a list of
- * <code>org.jboss.tm.XAWork</code>
- * instances containing one element for each
- * <code>XAResource</code> that is in a a heuristic status
- * @param completionHandler the
- * <code>org.jboss.tm.recovery.TxCompletionHandler</code> to be
- * notifed when the second phase of the 2PC completes.
- */
- public void recreateTransaction(LogRecord.HeurData heurData,
- List xaResourcesWithHeuristics,
- TxCompletionHandler completionHandler)
- {
- LocalId localIdObject = new LocalId(heurData.localTransactionId);
- TransactionImpl tx = (TransactionImpl) localIdTx.get(localIdObject);
- if (tx != null)
- {
- if (trace)
- log.trace("recreateTransaction called for existing transaction, " +
- "localId=" + heurData.localTransactionId + ", tx=" + tx +
- ", status=" + TxUtils.getStatusAsString(tx.getStatus()) +
- ", heuristicStatus=" + TxUtils.getXAErrorCodeAsString(
- heurData.heuristicStatusCode),
- new Throwable("[Stack trace]"));
- }
- else
- {
- tx = new TransactionImpl(heurData,
- xaResourcesWithHeuristics,
- completionHandler);
- localIdTx.put(tx.getLocalId(), tx);
- if (globalIdsEnabled)
- globalIdTx.put(tx.getGlobalId(), tx);
-
- if (trace)
- log.trace("recreated transaction with localId=" +
- heurData.localTransactionId + ", tx=" + tx +
- ", status=" + TxUtils.getStatusAsString(tx.getStatus()) +
- ", heuristicStatus=" + TxUtils.getXAErrorCodeAsString(
- heurData.heuristicStatusCode));
-
- //if (!tx.isImported())
- //{
- // tx.forget();
- //}
- }
- }
-
- // Implements TransactionLocalDelegate ----------------------
-
- public void lock(TransactionLocal local, Transaction tx) throws InterruptedException
- {
- TransactionImpl tximpl = (TransactionImpl) tx;
- tximpl.lock();
- }
-
- public void unlock(TransactionLocal local, Transaction tx)
- {
- TransactionImpl tximpl = (TransactionImpl) tx;
- tximpl.unlock();
- }
-
- public Object getValue(TransactionLocal local, Transaction tx)
- {
- TransactionImpl tximpl = (TransactionImpl) tx;
- return tximpl.getTransactionLocalValue(local);
- }
-
- public void storeValue(TransactionLocal local, Transaction tx, Object value)
- {
- TransactionImpl tximpl = (TransactionImpl) tx;
- tximpl.putTransactionLocalValue(local, value);
- }
-
- public boolean containsValue(TransactionLocal local, Transaction tx)
- {
- TransactionImpl tximpl = (TransactionImpl) tx;
- return tximpl.containsTransactionLocal(local);
- }
-
- // Implements StringRemoteRefConverter ----------------------------
-
- public Resource stringToResource(String strResource)
- {
- return TransactionImpl.stringToResource(strResource);
- }
-
- public RecoveryCoordinator stringToRecoveryCoordinator(
- String strRecCoordinator)
- {
- return TransactionImpl.stringToRecoveryCoordinator(strRecCoordinator);
- }
-
- public String resourceToString(Resource res)
- {
- return TransactionImpl.resourceToString(res);
- }
-
- public String recoveryCoordinatorToString(RecoveryCoordinator recoveryCoord)
- {
- return TransactionImpl.recoveryCoordinatorToString(recoveryCoord);
- }
-
- // Attribute getters and setters ----------------------------------
-
- /**
- * Setter for attribute <code>dtmEnabled</code>.
- */
- public void setDTMEnabled(boolean newValue)
- {
- if (newValue == true && !globalIdsEnabled)
- {
- // DTM requires global ids
- setGlobalIdsEnabled(newValue);
- }
- dtmEnabled = newValue;
- }
-
- /**
- * Setter for the DTM <code>CoordinatorFactory</code>.
- */
- public void setDTMCoordinatorFactory(
- CoordinatorFactory dtmCoordinatorFactory)
- {
- TransactionImpl.setDTMCoordinatorFactory(dtmCoordinatorFactory);
- }
-
- /**
- * Setter for the DTM <code>ResourceFactory</code>.
- */
- public void setDTMResourceFactory(ResourceFactory dtmResourceFactory)
- {
- TransactionImpl.setDTMResourceFactory(dtmResourceFactory);
- }
-
- /**
- * Setter for the OTS <code>ResourceFactory</code>.
- */
- public void setOTSResourceFactory(ResourceFactory otsResourceFactory)
- {
- TransactionImpl.setOTSResourceFactory(otsResourceFactory);
- }
-
- /**
- * Setter for the <code>OTSContextFactory</code>.
- */
- public void setOTSContextFactory(OTSContextFactory otsContextFactory)
- {
- TransactionImpl.setOTSContextFactory(otsContextFactory);
- }
-
- /**
- * Setter for the <code>interpositionEnabled</code> flag.
- */
- public void setInterpositionEnabled(boolean newValue)
- {
- TransactionImpl.setInterpositionEnabled(newValue);
- }
-
- /**
- * Getter for the <code>interpositionEnabled</code> flag.
- */
- public boolean getInterpositionEnabled()
- {
- return TransactionImpl.getInterpositionEnabled();
- }
-
- public void setDTMStringRemoteRefConverter(
- StringRemoteRefConverter otsStrRemoteRefConverter)
- {
- TransactionImpl.setDTMStrRemoteRefConverter(otsStrRemoteRefConverter);
- }
-
- public void setOTSStringRemoteRefConverter(
- StringRemoteRefConverter otsStrRemoteRefConverter)
- {
- TransactionImpl.setOTSStrRemoteRefConverter(otsStrRemoteRefConverter);
- }
-
- // Package protected ---------------------------------------------
-
- /**
- * Release the given TransactionImpl.
- */
- void releaseTransactionImpl(TransactionImpl tx)
- {
- localIdTx.remove(tx.getLocalId());
- if (globalIdsEnabled)
- globalIdTx.remove(tx.getGlobalId());
- }
-
- /**
- * Increment the commit count
- */
- void incCommitCount()
- {
- ++commitCount;
- }
-
- /**
- * Increment the rollback count
- */
- void incRollbackCount()
- {
- ++rollbackCount;
- }
-
- // Protected -----------------------------------------------------
-
- // Private -------------------------------------------------------
-
- /**
- * This keeps track of the thread association with transactions
- * and timeout values.
- * In some cases terminated transactions may not be cleared here.
- */
- private ThreadLocal threadTx = new ThreadLocal();
-
- /**
- * This map contains the active transactions as values.
- * The keys are the <code>LocalId</code>s of the transactions.
- */
- private Map localIdTx = Collections.synchronizedMap(new HashMap());
-
-
- /**
- * If <code>globalIdsEnabled</code> is true, this map associates
- * <code>GlobalId</code>s to active transactions.
- */
- private Map globalIdTx = Collections.synchronizedMap(new HashMap());
-
-
- /**
- * Return the ThreadInfo for the calling thread, and create if not
- * found.
- */
- private ThreadInfo getThreadInfo()
- {
- ThreadInfo ret = (ThreadInfo) threadTx.get();
-
- if (ret == null)
- {
- ret = new ThreadInfo();
- ret.timeout = timeOut;
- threadTx.set(ret);
- }
-
- return ret;
- }
-
- // Inner classes -------------------------------------------------
-
- /**
- * A simple aggregate of a thread-associated timeout value
- * and a thread-associated transaction.
- */
- static class ThreadInfo
- {
- long timeout;
- TransactionImpl tx;
- }
-
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/XidFactory.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/XidFactory.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/XidFactory.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,163 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm;
-
-import javax.transaction.xa.Xid;
-
-import org.jboss.system.ServiceMBeanSupport;
-
-/**
- * XidFactory.java
- * <p/>
- * <p/>
- * Created: Sat Jun 15 19:01:18 2002
- *
- * @author <a href="mailto:d_jencks at users.sourceforge.net">David Jencks</a>
- * @jmx.mbean
- */
-public class XidFactory
- extends ServiceMBeanSupport
- implements XidFactoryMBean
-{
-
- //default object name of the naming service
- private static final javax.management.ObjectName NAMING_OBJECT_NAME =
- org.jboss.mx.util.ObjectNameFactory.create("jboss:service=Naming");
-
- private XidFactoryImpl factory = new XidFactoryImpl();
-
- protected void startService()
- throws Exception
- {
- long jndiPortOrStartUpTime;
- try
- {
- Integer jndiPort =
- (Integer) getServer().getAttribute(NAMING_OBJECT_NAME, "Port");
- jndiPortOrStartUpTime = jndiPort.intValue();
- }
- catch (Exception e)
- {
- jndiPortOrStartUpTime = System.currentTimeMillis();
- }
- factory.setUniqueInstanceId(jndiPortOrStartUpTime);
- factory.start();
- }
-
- /**
- * mbean get-set pair for field instance
- * Get the value of instance
- *
- * @return value of instance
- * @jmx:managed-attribute
- */
- public XidFactoryMBean getInstance()
- {
- return this;
- }
-
- public String getBaseGlobalId()
- {
- return factory.getBaseGlobalId();
- }
-
- public void setBaseGlobalId(String baseGlobalId)
- {
- factory.setBaseGlobalId(baseGlobalId);
- }
-
- public long getGlobalIdNumber()
- {
- return factory.getGlobalIdNumber();
- }
-
- public void setGlobalIdNumber(long globalIdNumber)
- {
- factory.setGlobalIdNumber(globalIdNumber);
- }
-
- public String getBranchQualifier()
- {
- return factory.getBranchQualifier();
- }
-
- public void setBranchQualifier(String branchQualifier)
- {
- factory.setBranchQualifier(branchQualifier);
- }
-
- public boolean isPad()
- {
- return factory.isPad();
- }
-
- public void setPad(boolean pad)
- {
- factory.setPad(pad);
- }
-
- public XidImpl newXid()
- {
- return factory.newXid();
- }
-
- public XidImpl newBranch(GlobalId globalId)
- {
- return factory.newBranch(globalId);
- }
-
- public XidImpl newBranch(XidImpl xid,long branchIdNum)
- {
- return factory.newBranch(xid, branchIdNum);
- }
-
- public XidImpl recreateXid(long localId)
- {
- return factory.recreateXid(localId);
- }
-
- public XidImpl recreateXid(long localId, GlobalId globalId)
- {
- return factory.recreateXid(localId, globalId);
- }
-
- public byte[] localIdToGlobalId(long localId)
- {
- return factory.localIdToGlobalId(localId);
- }
-
- public long extractLocalIdFrom(byte[] globalId)
- {
- return factory.extractLocalIdFrom(globalId);
- }
-
- public String getBaseBranchQualifier(byte[] branchQualifier)
- {
- return factory.getBaseBranchQualifier(branchQualifier);
- }
-
- public String toString(Xid xid)
- {
- return factory.toString(xid);
- }
-
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/XidFactoryBase.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/XidFactoryBase.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/XidFactoryBase.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,146 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm;
-
-/**
- * Created by IntelliJ IDEA.
- * User: wburke
- * Date: May 3, 2005
- * Time: 2:48:26 PM
- * To change this template use File | Settings | File Templates.
- */
-public interface XidFactoryBase
-{
- /**
- * mbean get-set pair for field BaseGlobalId Get the value of BaseGlobalId
- * @return value of BaseGlobalId
- */
- String getBaseGlobalId() ;
-
- /**
- * Set the value of BaseGlobalId
- * @param BaseGlobalId Value to assign to BaseGlobalId
- */
- void setBaseGlobalId(String baseGlobalId) ;
-
- /**
- * mbean get-set pair for field globalIdNumber Get the value of globalIdNumber
- * @return value of globalIdNumber
- */
- long getGlobalIdNumber() ;
-
- /**
- * Set the value of globalIdNumber
- * @param globalIdNumber Value to assign to globalIdNumber
- */
- void setGlobalIdNumber(long globalIdNumber) ;
-
- /**
- * mbean get-set pair for field branchQualifier
- * Get the value of BranchQualifier
- * @return value of BranchQualifier
- */
- String getBranchQualifier() ;
-
- /**
- * Set the value of BranchQualifier
- * @param branchQualifier Value to assign to BranchQualifier
- */
- void setBranchQualifier(String branchQualifier) ;
-
- /**
- * mbean get-set pair for field pad Get the value of pad
- * @return value of pad
- */
- boolean isPad() ;
-
- /**
- * Set the value of pad
- * @param pad Value to assign to pad
- */
- void setPad(boolean pad) ;
-
- /**
- * Creates a <code>XidImpl</code> for a new transaction.
- * @return a <code>XidImpl</code> value
- */
- XidImpl newXid() ;
-
- /**
- * Creates a <code>XidImpl</code> for a branch of an existing transaction.
- * @param globalId the code>GlobalId</code> of the existing transaction
- * @return a <code>XidImpl</code> tor the new transaction branch.
- */
- XidImpl newBranch(GlobalId globalId);
-
- /**
- * Creates a <code>XidImpl</code> for a "fake branch" of an existing
- * transaction. This method exists for a single reason: some
- * <code>XAResource</code> implementations return false on all calls to
- * <code>isSameRM</code>. If <code>isSameRM</code> worked properly, then
- * there would be no need to generate a "fake branch" Xid for each
- * <code>XAResource</code> that may or may not represent a new RM. A same
- * <code>Xid</code> (the real <code>Xid</code> for the transaction branch)
- * could (and should) be used for all <code>XAResource</code>s that
- * represent different RMs. If <code>isSameRM</code> may return false
- * negatives, however, the real branch Xid may be passed more than once
- * to a same RM in calls to <code>XAResource.start</code>. This would result
- * in <code>XAException</code>s with error code <code>XAER_DUPID</code>.
- * We avoid this problem by generating a "fake branch" <code>Xid</code>
- * for each <code>XAResource</code> that corresponds to a "new" RM according
- * to <code>isSameRM</code>, but might actually not represent a new one.
- *
- * @param xid a <code>XidImpl</code> for the existing transaction
- * @param branchNum a branch number to be included in the branch qualifier.
- * @return a <code>XidImpl</code> for the new transaction branch.
- */
- XidImpl newBranch(XidImpl xid,long branchIdNum);
-
- XidImpl recreateXid(long localId);
-
- XidImpl recreateXid(long localId, GlobalId globalId);
-
- /**
- * Converts a local id into a global transaction id.
- *
- * @param localId the local transaction id
- * @return the global transaction id
- */
- public byte[] localIdToGlobalId(long localId);
-
- /**
- * Extracts the local id contained in a global id.
- * @param globalId a global id
- * @return the local id extracted from the global id
- */
- long extractLocalIdFrom(byte[] globalId) ;
-
- String getBaseBranchQualifier(byte[] branchQualifier);
-
- /**
- * Describe <code>toString</code> method here.
- * @param xid a <code>Xid</code> value
- * @return a <code>String</code> value
- */
- String toString(javax.transaction.xa.Xid xid) ;
-
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/XidFactoryImpl.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/XidFactoryImpl.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/XidFactoryImpl.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,405 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm;
-
-import javax.transaction.xa.Xid;
-
-import org.jboss.system.server.ServerConfigUtil;
-
-/**
- * XidFactory.java
- * <p/>
- * <p/>
- * Created: Sat Jun 15 19:01:18 2002
- *
- * @author <a href="mailto:d_jencks at users.sourceforge.net">David Jencks</a>
- * @jmx.mbean
- */
-public class XidFactoryImpl
- implements XidFactoryBase
-{
-
- /**
- * The default value of baseGlobalId is the host name, followed by a
- * colon (":"), the server's JNDI port, and a slash. It the server's JNDI
- * port cannot be obtained, then the startService time is used instead.
- * <p/>
- * This is used for building globally unique transaction identifiers.
- * It would be safer to use the IP address, but a host name is better
- * for humans to read and will do for now.
- */
- private String baseGlobalId;
-
- /**
- * The next transaction id to use on this host.
- */
- private long globalIdNumber = 0;
-
- /**
- * The variable <code>pad</code> says whether the byte[] should be their
- * maximum 64 byte length or the minimum.
- * The max length is required for Oracle..
- */
- private boolean pad = false;
-
- /**
- * The <code>branchQualifier</code> is the host name, followed by a
- * colon (":") and the server's JNDI port. It the server's JNDI
- * port cannot be obtained, then the startService time is used instead.
- */
- private String branchQualifier;
-
- /**
- * This field stores the byte reprsentation of baseGlobalId
- * to avoid the expensive getBytes() call on that String object
- * when we create a new Xid, which we do VERY often!
- */
- private byte[] baseGlobalIdBytes;
-
- /**
- * This field stores the byte reprsentation of branchQualifier
- * to avoid the expensive getBytes() call on that String object.
- */
- private byte[] branchQualifierBytes;
-
- /**
- * This field stores the byte reprsentation of base branchQualifier
- * to avoid the expensive getBytes() call on that String object.
- */
- private byte[] baseBranchQualifierBytes;
-
- private long uniqueInstanceId = System.currentTimeMillis();
-
- public void start()
- {
- String hostName = ServerConfigUtil.getSpecificBindAddress();
-
- baseGlobalId = hostName + ":" + uniqueInstanceId;
- // Ensure room for 14 digits of serial no and timestamp
- if (baseGlobalId.length() > Xid.MAXGTRIDSIZE - 15)
- baseGlobalId = baseGlobalId.substring(0, Xid.MAXGTRIDSIZE - 15);
- baseGlobalId = baseGlobalId + "/";
- baseGlobalIdBytes = baseGlobalId.getBytes();
-
- branchQualifier = hostName + ":" + uniqueInstanceId;
- int len = pad ? Xid.MAXBQUALSIZE : branchQualifier.length();
- branchQualifierBytes = new byte[len];
- // this method is deprecated, but does exactly what we need in a very fast
- // way the default conversion from String.getBytes() is way too expensive
- branchQualifier.getBytes(0, branchQualifier.length(),
- branchQualifierBytes, 0);
-
- String baseBranchQualifier = branchQualifier + "/";
- baseBranchQualifierBytes = new byte[baseBranchQualifier.length()];
- // use deprecated method again
- baseBranchQualifier.getBytes(0, baseBranchQualifier.length(),
- baseBranchQualifierBytes, 0);
-
- }
-
- public long getUniqueInstanceId()
- {
- return uniqueInstanceId;
- }
-
- public void setUniqueInstanceId(long uniqueInstanceId)
- {
- this.uniqueInstanceId = uniqueInstanceId;
- }
-
- /**
- * mbean get-set pair for field BaseGlobalId
- * Get the value of BaseGlobalId
- *
- * @return value of BaseGlobalId
- * @jmx:managed-attribute
- */
- public String getBaseGlobalId()
- {
- return baseGlobalId;
- }
-
- /**
- * Set the value of BaseGlobalId
- *
- * @param BaseGlobalId Value to assign to BaseGlobalId
- * @jmx:managed-attribute
- */
- public void setBaseGlobalId(final String baseGlobalId)
- {
- this.baseGlobalId = baseGlobalId;
- baseGlobalIdBytes = baseGlobalId.getBytes();
- }
-
- /**
- * mbean get-set pair for field globalIdNumber
- * Get the value of globalIdNumber
- *
- * @return value of globalIdNumber
- * @jmx:managed-attribute
- */
- public synchronized long getGlobalIdNumber()
- {
- return globalIdNumber;
- }
-
- /**
- * Set the value of globalIdNumber
- *
- * @param globalIdNumber Value to assign to globalIdNumber
- * @jmx:managed-attribute
- */
- public synchronized void setGlobalIdNumber(final long globalIdNumber)
- {
- this.globalIdNumber = globalIdNumber;
- }
-
- /**
- * mbean get-set pair for field BranchQualifier
- * Get the value of BranchQualifier
- *
- * @return value of BranchQualifier
- * @jmx:managed-attribute
- */
- public String getBranchQualifier()
- {
- return branchQualifier;
- }
-
- /**
- * Set the value of BranchQualifier
- *
- * @param branchQualifier Value to assign to BranchQualifier
- * @jmx:managed-attribute
- */
- public void setBranchQualifier(final String branchQualifier)
- {
- this.branchQualifier = branchQualifier;
-
- int len = pad ? Xid.MAXBQUALSIZE : branchQualifier.length();
- branchQualifierBytes = new byte[len];
- // This method is deprecated, but does exactly what we need in a
- // very fast way. The default conversion from String.getBytes()
- // is way too expensive.
- branchQualifier.getBytes(0, branchQualifier.length(),
- branchQualifierBytes, 0);
-
- String baseBranchQualifier = branchQualifier + "/";
- baseBranchQualifierBytes = new byte[baseBranchQualifier.length()];
- // use deprecated method again
- baseBranchQualifier.getBytes(0, baseBranchQualifier.length(),
- baseBranchQualifierBytes, 0);
- }
-
- /**
- * mbean get-set pair for field pad
- * Get the value of pad
- *
- * @return value of pad
- * @jmx:managed-attribute
- */
- public boolean isPad()
- {
- return pad;
- }
-
- /**
- * Set the value of pad
- *
- * @param pad Value to assign to pad
- * @jmx:managed-attribute
- */
- public void setPad(boolean pad)
- {
- if (this.pad != pad)
- {
- this.pad = pad;
- if (branchQualifier != null)
- {
- // update branchQualifierBytes according to the new value of pad
- int len = pad ? Xid.MAXBQUALSIZE : branchQualifier.length();
- branchQualifierBytes = new byte[len];
- // This method is deprecated, but does exactly what we need in a
- // very fast way. The default conversion from String.getBytes()
- // is way too expensive.
- branchQualifier.getBytes(0, branchQualifier.length(),
- branchQualifierBytes, 0);
- }
- }
-
- }
-
- /**
- * Creates a <code>XidImpl</code> for a new transaction.
- *
- * @return a <code>XidImpl</code> value
- * @jmx.managed-operation
- */
- public XidImpl newXid()
- {
- long localId = getNextId();
- return new XidImpl(localIdToGlobalId(localId),
- branchQualifierBytes,
- (int) localId,
- localId);
- }
-
- /**
- * Creates a <code>XidImpl</code> for a branch of an existing transaction.
- *
- * @param globalId the code>GlobalId</code> of the existing transaction
- * @return a <code>XidImpl</code> tor the new transaction branch.
- * @jmx.managed-operation
- */
- public XidImpl newBranch(GlobalId globalId)
- {
- long localId = getNextId();
- return new XidImpl(globalId, branchQualifierBytes, localId);
- }
-
- /**
- * Creates a <code>XidImpl</code> for a "fake branch" of an existing
- * transaction. This method exists for a single reason: some
- * <code>XAResource</code> implementations return false on all calls to
- * <code>isSameRM</code>. If <code>isSameRM</code> worked properly, then
- * there would be no need to generate a "fake branch" Xid for each
- * <code>XAResource</code> that may or may not represent a new RM. A same
- * <code>Xid</code> (the real <code>Xid</code> for the transaction branch)
- * could (and should) be used for all <code>XAResource</code>s that
- * represent different RMs. If <code>isSameRM</code> may return false
- * negatives, however, the real branch Xid may be passed more than once
- * to a same RM in calls to <code>XAResource.start</code>. This would result
- * in <code>XAException</code>s with error code <code>XAER_DUPID</code>.
- * We avoid this problem by generating a "fake branch" <code>Xid</code>
- * for each <code>XAResource</code> that corresponds to a "new" RM according
- * to <code>isSameRM</code>, but might actually not represent a new one.
- *
- * @param xid a <code>XidImpl</code> for the existing transaction
- * @param branchNum a branch number to be included in the branch qualifier.
- * @return a <code>XidImpl</code> for the new transaction branch.
- * @jmx.managed-operation
- */
- public XidImpl newBranch(XidImpl xid, long branchNum)
- {
- String id = Long.toString(branchNum);
- int len = pad ? Xid.MAXBQUALSIZE
- : baseBranchQualifierBytes.length + id.length();
- byte[] branchQualifier = new byte[len];
- System.arraycopy(baseBranchQualifierBytes, 0,
- branchQualifier, 0,
- baseBranchQualifierBytes.length);
- // This method is deprecated, but does exactly what we need in a very
- // fast way. The conversion via String.getBytes() is way too expensive.
- id.getBytes(0, id.length(), branchQualifier,
- baseBranchQualifierBytes.length);
- return new XidImpl(xid, branchQualifier);
- }
-
- public XidImpl recreateXid(long localId)
- {
- return new XidImpl(localIdToGlobalId(localId),
- branchQualifierBytes,
- (int) localId,
- localId);
- }
-
- public XidImpl recreateXid(long localId, GlobalId globalId)
- {
- return new XidImpl(globalId, branchQualifierBytes, localId);
- }
-
- /**
- * Converts a local id into a global transaction id.
- *
- * @param localId the local transaction id
- * @return the global transaction id
- */
- public byte[] localIdToGlobalId(long localId)
- {
- String id = Long.toString(localId);
- int len = pad ? Xid.MAXGTRIDSIZE : id.length() + baseGlobalIdBytes.length;
- byte[] globalId = new byte[len];
- System.arraycopy(baseGlobalIdBytes, 0, globalId, 0, baseGlobalIdBytes.length);
- // this method is deprecated, but does exactly what we need in a very fast way
- // the default conversion from String.getBytes() is way too expensive
- id.getBytes(0, id.length(), globalId, baseGlobalIdBytes.length);
- return globalId;
- }
-
- /**
- * Extracts the local id contained in a global id.
- *
- * @param globalId a global id
- * @return the local id extracted from the global id
- * @jmx:managed-operation
- */
- public long extractLocalIdFrom(byte[] globalId)
- {
- int i, start;
- int len = globalId.length;
-
- for (i = 0; globalId[i++] != (byte) '/';)
- ;
- start = i;
- while (i < len && globalId[i] != 0)
- i++;
- String globalIdNumber = new String(globalId, 0, start, i - start);
- return Long.parseLong(globalIdNumber);
- }
-
- /**
- * @param branchQualifier
- * @return
- * @jmx:managed-operation
- */
- public String getBaseBranchQualifier(byte[] branchQualifier)
- {
- int len = branchQualifier.length;
- int i = 0;
-
- while (branchQualifier[i] != (byte) '/'
- && branchQualifier[i] != (byte) 0
- && i < len)
- i++;
-
- String base = new String(branchQualifier, 0, 0, i);
- return base;
- }
-
- /**
- * Describe <code>toString</code> method here.
- *
- * @param xid a <code>Xid</code> value
- * @return a <code>String</code> value
- * @jmx.managed-operation
- */
- public String toString(Xid xid)
- {
- return XidImpl.toString(xid);
- }
-
- private synchronized long getNextId()
- {
- return ++globalIdNumber;
- }
-
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/XidFactoryMBean.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/XidFactoryMBean.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/XidFactoryMBean.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,35 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm;
-
-/**
- * MBean interface.
- */
-public interface XidFactoryMBean extends org.jboss.system.ServiceMBean, XidFactoryBase {
-
- /**
- * mbean get-set pair for field instance Get the value of instance
- * @return value of instance
- */
- XidFactoryMBean getInstance() ;
-
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/XidImpl.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/XidImpl.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/XidImpl.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,351 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm;
-
-import javax.transaction.xa.Xid;
-
-/**
- * This object encapsulates the ID of a transaction.
- * This implementation is immutable and always serializable at runtime.
- *
- * @see TransactionImpl
- * @author <a href="mailto:rickard.oberg at telkel.com">Rickard ???berg</a>
- * @author <a href="mailto:osh at sparre.dk">Ole Husgaard</a>
- * @author <a href="reverbel at ime.usp.br">Francisco Reverbel</a>
- * @version $Revision$
- */
-public class XidImpl
- implements Xid, java.io.Serializable
-{
- // Constants -----------------------------------------------------
-
- static final long serialVersionUID = -4175838107150528488L;
-
- public static final int JBOSS_FORMAT_ID = 0x0101;
-
- // Static variable -----------------------------------------------
-
- private static boolean trulyGlobalIdsEnabled = false;
-
- // Attributes ----------------------------------------------------
-
- /**
- * Format id of this instance.
- * A JBoss-generated Xids has JBOSS_FORMAT_ID in this field.
- */
- private final int formatId;
-
- /**
- * Global transaction id of this instance.
- * The coding of this class depends on the fact that this variable is
- * initialized in the constructor and never modified. References to
- * this array are never given away, instead a clone is delivered.
- */
- private final byte[] globalId;
-
- /**
- * Branch qualifier of this instance.
- * This identifies the branch of a transaction.
- */
- private final byte[] branchId;
-
- /**
- * Hash code of this instance. This is really a sequence number.
- */
- private final int hash;
-
- /**
- * Local id of this instance. This field uniquely identifies a
- * transaction within a given JBoss server.
- */
- private final long localId;
-
- /**
- * Global id of this instance. This field uniquely identifies a
- * transaction in a distributed environment.
- */
- private final GlobalId trulyGlobalId;
-
-
- // Static --------------------------------------------------------
-
- /**
- * Setter for class variable trulyGlobalIdsEnabled.
- */
- public static void setTrulyGlobalIdsEnabled(boolean newValue)
- {
- trulyGlobalIdsEnabled = newValue;
- }
-
- /**
- * Getter for class variable trulyGlobalIdsEnabled.
- */
- public static boolean getTrulyGlobalIdsEnabled()
- {
- return trulyGlobalIdsEnabled;
- }
-
- /**
- * Return a string that describes any Xid instance.
- */
- public static String toString(Xid id)
- {
- if (id == null)
- return "[NULL Xid]";
-
- String s = id.getClass().getName();
- s = s.substring(s.lastIndexOf('.') + 1);
- s = s + "[FormatId=" + id.getFormatId()
- + ", GlobalId=" + new String(id.getGlobalTransactionId()).trim()
- + ", BranchQual=" + new String(id.getBranchQualifier()).trim()
- + ((id instanceof XidImpl)
- ? ", localId=" + LocalId.toString(((XidImpl)id).localId )
- : "")
- + "]";
-
- return s;
- }
-
- // Constructors --------------------------------------------------
-
- /**
- * Create a new instance.
- */
- public XidImpl(int formatId,
- byte[] globalId, byte[] branchId, int hash, long localId)
- {
- this.formatId = formatId;
- this.globalId = globalId;
- this.branchId = branchId;
- this.hash = hash;
- this.localId = localId;
- this.trulyGlobalId = (trulyGlobalIdsEnabled)
- ? new GlobalId(formatId, globalId)
- : null;
- }
-
- /**
- * Create a new instance with JBOSS_FORMAT_ID.
- */
- XidImpl(byte[] globalId, byte[] branchId, int hash, long localId)
- {
- this.formatId = JBOSS_FORMAT_ID;
- this.globalId = globalId;
- this.branchId = branchId;
- this.hash = hash;
- this.localId = localId;
- this.trulyGlobalId = (trulyGlobalIdsEnabled)
- ? new GlobalId(JBOSS_FORMAT_ID, globalId, hash)
- : null;
- }
-
- /**
- * Create a new branch of an existing global transaction ID.
- *
- * @param xidImpl The transaction ID to create a new branch of.
- * @param branchId The ID of the new branch.
- *
- */
- public XidImpl(final XidImpl xidImpl, final byte[] branchId)
- {
- this.formatId = xidImpl.formatId;
- this.globalId = xidImpl.globalId; // reuse array, we never modify it
- this.branchId = branchId;
- this.hash = xidImpl.hash;
- this.localId = xidImpl.localId;
- this.trulyGlobalId = (trulyGlobalIdsEnabled)
- ? xidImpl.trulyGlobalId
- : null;
- }
-
- /**
- * Create a new branch of an existing global transaction.
- *
- * @param globalId identifies the transaction to create a new branch of
- * @param branchId the id that distiguishes the new branch from other
- * branches of the same transaction
- * @param localId the local id of the transaction
- *
- */
- public XidImpl(final GlobalId globalId, final byte[] branchId, long localId)
- {
- this.formatId = globalId.getFormatId();
- this.globalId = globalId.getGlobalTransactionId();
- this.branchId = branchId;
- this.hash = globalId.hashCode();
- this.localId = localId;
- this.trulyGlobalId = (trulyGlobalIdsEnabled)
- ? globalId
- : null;
- }
-
- // Public --------------------------------------------------------
-
- // Xid implementation --------------------------------------------
-
- /**
- * Return the global transaction id of this transaction.
- */
- public byte[] getGlobalTransactionId()
- {
- return (byte[])globalId.clone();
- }
-
- /**
- * Return the branch qualifier of this transaction.
- */
- public byte[] getBranchQualifier()
- {
- if (branchId.length == 0)
- return branchId; // Zero length arrays are immutable.
- else
- return (byte[])branchId.clone();
- }
-
- /**
- * Return the format identifier of this transaction.
- *
- * The format identifier augments the global id and specifies
- * how the global id and branch qualifier should be interpreted.
- */
- public int getFormatId()
- {
- // The id we return here should be different from all other transaction
- // implementations.
- // Known IDs are:
- // -1: Sometimes used to denote a null transaction id.
- // 0: OSI TP (javadoc states OSI CCR, but that is a bit misleading
- // as OSI CCR doesn't even have ACID properties. But OSI CCR and
- // OSI TP do have the same id format.)
- // 1: Was used by early betas of jBoss.
- // 0x0101: The JBOSS_FORMAT_ID we use here.
- // 0xBB14: Used by JONAS.
- // 0xBB20: Used by JONAS.
-
- return formatId;
- }
-
- /**
- * Compare for equality.
- *
- * Instances are considered equal if they are both instances of XidImpl,
- * and if they have the same format id, the same global transaction id
- * and the same transaction branch qualifier.
- */
- public boolean equals(Object obj)
- {
- if(obj==this)
- return true;
- if (obj instanceof XidImpl) {
- XidImpl other = (XidImpl)obj;
-
- if (formatId != other.formatId ||
- globalId.length != other.globalId.length ||
- branchId.length != other.branchId.length)
- return false;
-
- for (int i = 0; i < globalId.length; ++i)
- if (globalId[i] != other.globalId[i])
- return false;
-
- for (int i = 0; i < branchId.length; ++i)
- if (branchId[i] != other.branchId[i])
- return false;
-
- return true;
- }
- return false;
- }
-
- public int hashCode()
- {
- return hash;
- }
-
- public String toString()
- {
- return toString(this);
- }
-
- // Methods specific to JBoss Xid implementation ------------------
-
- /**
- * Return the local id that identifies this transaction
- * within the JBoss server.
- */
- public long getLocalIdValue()
- {
- return localId;
- }
-
- /**
- * Return a LocalId instance that identifies this transaction
- * within the JBoss server.
- */
- public LocalId getLocalId()
- {
- return new LocalId(localId);
- }
-
- /**
- * Return a GlobalId instance that identifies this transaction
- * in a distributed environment.
- */
- public GlobalId getTrulyGlobalId()
- {
- return trulyGlobalId;
- }
-
- /**
- * Compare for same transaction.
- *
- * Instances represent the same transaction if they have the same
- * format id and global transaction id.
- */
- public boolean sameTransaction(XidImpl other)
- {
- if(other == this)
- return true;
- if (formatId != other.formatId ||
- globalId.length != other.globalId.length)
- return false;
-
- for (int i = 0; i < globalId.length; ++i)
- if (globalId[i] != other.globalId[i])
- return false;
-
- return true;
- }
-
- /**
- * Return the global transaction id of this transaction.
- * Unlike the {@link #getGlobalTransactionId()} method, this one
- * returns a reference to the global id byte array that may <em>not</em>
- * be changed.
- */
- public byte[] getInternalGlobalTransactionId()
- {
- return globalId;
- }
-
-}
-
Deleted: trunk/transaction/src/main/org/jboss/tm/integrity/AbstractTransactionIntegrity.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/integrity/AbstractTransactionIntegrity.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/integrity/AbstractTransactionIntegrity.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,63 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.integrity;
-
-import javax.transaction.Transaction;
-
-import org.jboss.logging.Logger;
-import org.jboss.tm.TransactionImpl;
-
-/**
- * A NOOP implementation of transaction integrity.<p>
- *
- * Implementations should extend this for future compatibility.
- *
- * @author <a href="adrian at jboss.com">Adrian Brock</a>
- * @version $Revision$
- */
-public class AbstractTransactionIntegrity implements TransactionIntegrity
-{
- /** The log */
- protected Logger log = Logger.getLogger(getClass());
-
- public void checkTransactionIntegrity(TransactionImpl transaction)
- {
- // Do nothing
- }
-
- /**
- * Mark the transaction for rollback
- *
- * @param transaction the transacton
- */
- protected void markRollback(Transaction transaction)
- {
- try
- {
- transaction.setRollbackOnly();
- }
- catch (Exception e)
- {
- log.warn("Unable to mark the transaction for rollback " + transaction, e);
- }
- }
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/integrity/FailIncompleteTransaction.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/integrity/FailIncompleteTransaction.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/integrity/FailIncompleteTransaction.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,40 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.integrity;
-
-import org.jboss.system.ServiceMBeanSupport;
-
-/**
- * An MBean to configure the FailIncomplete policy.
- *
- * @author <a href="adrian at jboss.com">Adrian Brock</a>
- * @version $Revision$
- */
-public class FailIncompleteTransaction extends ServiceMBeanSupport
- implements FailIncompleteTransactionMBean
-{
- public TransactionIntegrity createTransactionIntegrity()
- {
- return new FailIncompleteTransactionIntegrity();
- }
-
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/integrity/FailIncompleteTransactionIntegrity.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/integrity/FailIncompleteTransactionIntegrity.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/integrity/FailIncompleteTransactionIntegrity.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,61 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.integrity;
-
-import java.util.Set;
-
-import org.jboss.tm.TransactionImpl;
-
-/**
- * A transaction integrity that rolls back the transaction
- * if there are other threads associated with it.
- *
- * @author <a href="adrian at jboss.com">Adrian Brock</a>
- * @version $Revision$
- */
-public class FailIncompleteTransactionIntegrity extends AbstractTransactionIntegrity
-{
- public void checkTransactionIntegrity(TransactionImpl transaction)
- {
- // Assert the only thread is ourselves
- Set threads = transaction.getAssociatedThreads();
- String rollbackError = null;
- synchronized (threads)
- {
- if (threads.size() > 1)
- rollbackError = "Too many threads " + threads + " associated with transaction " + transaction;
- else if (threads.size() != 0)
- {
- Thread other = (Thread) threads.iterator().next();
- Thread current = Thread.currentThread();
- if (current.equals(other) == false)
- rollbackError = "Attempt to commit transaction " + transaction + " on thread " + current +
- " with other threads still associated with the transaction " + other;
- }
- }
- if (rollbackError != null)
- {
- log.error(rollbackError, new IllegalStateException("STACKTRACE"));
- markRollback(transaction);
- }
- }
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/integrity/FailIncompleteTransactionMBean.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/integrity/FailIncompleteTransactionMBean.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/integrity/FailIncompleteTransactionMBean.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,29 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.integrity;
-
-import org.jboss.system.ServiceMBean;
-
-public interface FailIncompleteTransactionMBean extends ServiceMBean, TransactionIntegrityFactory
-{
-
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/integrity/TransactionIntegrity.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/integrity/TransactionIntegrity.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/integrity/TransactionIntegrity.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,51 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.integrity;
-
-import org.jboss.tm.TransactionImpl;
-
-/**
- * A policy that checks a transaction before allowing a commit
- *
- * @author <a href="adrian at jboss.com">Adrian Brock</a>
- * @version $Revision$
- */
-public interface TransactionIntegrity
-{
- /**
- * Checks whether a transaction can be committed.<p>
- *
- * The policy is allowed to wait, e.g. if there
- * are other threads still associated with the transaction.<p>
- *
- * This method is invoked before any transaction synchronizations'
- * beforeCompletions.<p>
- *
- * This policy should not invoke any methods that change the
- * state of the transaction other than <code>setRollbackOnly()</code>
- * to force a rollback or registering a transaction synchronization.
- *
- * @param transaction the transaction
- * @throws SecurityException if a commit is not allowed from this context
- */
- void checkTransactionIntegrity(TransactionImpl transaction);
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/integrity/TransactionIntegrityFactory.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/integrity/TransactionIntegrityFactory.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/integrity/TransactionIntegrityFactory.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,38 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.integrity;
-
-/**
- * A transaction integrity factory
- *
- * @author <a href="adrian at jboss.com">Adrian Brock</a>
- * @version $Revision$
- */
-public interface TransactionIntegrityFactory
-{
- /**
- * Create a new transaction integrity policy
- *
- * @return the transaction integrity policy
- */
- TransactionIntegrity createTransactionIntegrity();
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/package.html
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/package.html 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/package.html 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,152 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html>
- <head>
- <!--
- JBoss, Home of Professional Open Source
- Copyright 2005, 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.
- -->
- <!-- $Id$ -->
- </head>
-
- <body bgcolor="white">
- <p><em>The default Transaction Manager implementation</em>.
-
-
- <h2>Package Specification</h2>
- <ul>
-
-The classes in this package belong may be grouped into two:
-<ul>
- <li><em>Application server interface</em>. This group consists of the
- two classes {@link: TransactionPropagationContextFactory} and
- {@link: TransactionPropagationContextImporter}. Together these two
- classes form the JBoss-specific Communication Resource Manager (CRM).
- </li>
- <li><em>The default Transaction Service</em>. This is the rest of the
- classes in this package. It is a very fast JTA implementation with
- two drawbacks:
- <ul>
- <li>
- It has no transactional logging or recovery after server crashes.
- </li>
- <li>
- Transactions cannot be propagated from one server VM to another.
- But the thin-client UserTransaction service works fine, in case
- you just want to control transactions on a single server from your
- stand-alone clients.
- </li>
- </ul>
- </li>
-
-</ul>
- </ul>
-
- <h2>The JBoss-specific Communication Resource Manager</h2>
- <p>A CRM is responsible for converting local transactions from/to a
- form that can be serialized so it can be passed over the wire to
- another Java VM.</p>
- <p>The JTA specification does not define the CRM, so we have implemented
- our own.</p>
- <p>The J2EE specification suggests that the CRM used is the OTS
- CosTSPortability CRM, but that depends heavily on CORBA, and JBoss is
- not dependent on any particular object request broker technology, so
- we do not use that.</p>
- <p>The advantage of using our own CRM implementation instead of
- CosTSPortablilty is twofold:
- <ul>
- <li>
- JBoss does not depend on CORBA, and will run just fine without it.
- </li>
- <li>
- JBoss is able to use JTA implementations that are completely
- incompatible with OTS.
- </li>
- </ul>
-
- <h2>Adapting an existing JTA implementation for JBoss</h2>
- <p>In JBoss everything is a MBean. Implementing your JTA implementation
- as an MBean makes it simpler to manage it in a standardized way.</p>
- Since your JTA implementation is a service you probably want to make
- your MBean implemementation extend from
- <code>org.jboss.system.ServiceMBeanSupport</code>.</p>
- When running in the server, your MBean should publish three objects
- in JNDI:
- <ul>
- <li>
- <em>java:/TransactionManager</em>
- When this JNDI name is looked up, it should return an object instance
- that implements <code>javax.transaction.TransactionManager</code>.
- This is the standard JTA transaction manager that the JBoss server
- uses to control transactions.
- </li>
- <li>
- <em>java:/TransactionPropagationContextImporter</em>
- When this JNDI name is looked up, it should return an object instance
- that implements
- <code>org.jboss.tm.TransactionPropagationContextImporter</code>.
- This is used by the JBoss communication layers to convert the wire
- representation of a transaction to a
- <code>javax.transaction.Transaction</code> instance that can be used
- locally.
- </li>
- <li>
- <em>java:/TransactionPropagationContextFactory</em>
- When this JNDI name is looked up, it should return an object instance
- that implements
- <code>org.jboss.tm.TransactionPropagationContextFactory</code>.
- This is used by the JBoss communication layers to convert the wire
- representation of a <code>javax.transaction.Transaction</code>
- instance to a form that can be passed over the wire to another JBoss
- server.
- </li>
- </ul>
- <p>See the implementation of
- <code>org.jboss.tm.TransactionManagerService</code> for an example of
- such a MBean. Please note that the three names your MBean should publish
- in JNDI need not refer to the same object instance as the
- <code>TransactionManagerService</code> does.</p>
-
- <p>Please note that the transaction propagation context (TPC) used by
- the CRM interfaces <code>TransactionPropagationContextImporter</code>
- and <code>TransactionPropagationContextFactory</code> is of type
- <code>java.lang.Object</code>. This allows for the widest range of
- possible TPC implementations. For your TPC to work with the JBoss
- JRMP transport, it should be Java-serializable at runtime.</p>
-
- <h2>Related Documentation</h2>
- <ul>
- <li>
- <a href="http://java.sun.com/products/jta/">The JTA specification</a>
- </li>
- <li>
- <a href="http://www.omg.org/technology/documents/formal/transaction_service.htm">The OTS specification</a>
- </li>
- </ul>
-
- <h2>Package Status</h2>
- <ul>
- <li><font color="green"><b>STABLE</b></font>
- </ul>
-
- <!-- Put @see and @since tags down here. -->
-
- </body>
-</html>
-
Deleted: trunk/transaction/src/main/org/jboss/tm/recovery/BatchLog.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/recovery/BatchLog.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/recovery/BatchLog.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,413 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.recovery;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.ObjectOutputStream;
-import java.io.RandomAccessFile;
-import java.nio.ByteBuffer;
-import java.nio.channels.FileChannel;
-
-import org.jboss.logging.Logger;
-
-/**
- * Class that encapsulates a log file opened for writing. It provides
- * <code>write</code> methods that append log records to the log file.
- * A <code>BatchLog</code> instance belongs to some <code>BatchWriter</code>
- * and its write methods are called only from the <code>BatchWriter</code>
- * thread.
- * <p>
- * To avoid changes in its metadata, the log file is created with a fixed
- * length, which should never change until the file is closed.
- * <p>
- * A newly created log file is clean: it contains a header object followed
- * by a sequence of null bytes that takes the entire lenght of the file. Log
- * files are reusable, but they must be cleaned up for reuse. Restarting a
- * <code>BatchLog</code> means overwriting with null bytes all the data that
- * follows the header and returning the <code>BatchLog</code> to the pool of
- * clean <code>BatchLog</code> instances maintained by a
- * <code>BatchWriter</code>.
- *
- * @author <a href="mailto:bill at jboss.org">Bill Burke</a>
- * @author <a href="mailto:reverbel at ime.usp.br">Francisco Reverbel</a>
- * @version $Revision$
- */
-class BatchLog
- implements TxCompletionHandler
-{
- /**
- * Class <code>Logger</code>, for trace messages.
- */
- private static Logger errorLog = Logger.getLogger(BatchLog.class);
-
- /**
- * Length of the null-filled buffer used to clean log file.
- */
- private static final int CLEAN_LENGTH = 16 * 1024;
-
- /**
- * Buffer used to fill the log file with null bytes.
- */
- private static byte[] nulls = new byte[CLEAN_LENGTH];
-
- /**
- * The log file.
- */
- private File logFile;
-
- /**
- * A <code>RandomAccessFile</code> view of the log file.
- */
- private RandomAccessFile os;
-
- /**
- * The <code>RandomAccessFile</code>'s underlying <code>FileChannel</code>.
- */
- private FileChannel channel;
-
- /**
- * Number of transactions logged. Counts commit, multi-TM commit, prepare,
- * and JCA prepare records written out to the log. Only the
- * <code>BatchWriter</code> thread updates this field, which is declared
- * as volatile so that its updates are seen by any threads that call
- * <code>handleTxCompletion</code>.
- */
- private volatile int numLoggedTransactions;
-
- /**
- * Number of end records written out to the log. Only the
- * <code>BatchWriter</code> thread updates this field, which is declared
- * as volatile so that its updates are seen by any threads that call
- * <code>handleTxCompletion</code>.
- */
- private volatile int numEndRecords;
-
- /**
- * Number of completed transactions that need no end records. Access to this
- * field is synchronized, as it is concurrently updated via calls to
- * <code>handleTxCompletion</code>.
- */
- private int numLocalTransactionsCompleted;
-
- /**
- * Indicates that this <code>BatchLog</code> will not receive additional
- * records for new transactions. This <code>BatchLog</code> should be
- * cleaned up and returned to the <code>BatchWriter</code>'s pool of clean
- * <code>BatchLog</code> instances as soon as every outstanding transaction
- * signals its completion either by writing out an end record or by invoking
- * <code>handleTxCompletion</code>.
- */
- private boolean markedForRestart;
-
- /**
- * Header object written to the beginning of the log file via Java
- * serialization. It is preceded by four bytes (an int value) with the
- * length of the serialized header.
- */
- private Object header;
-
- /**
- * Log file position that follows the four bytes with the header lenght and
- * the header object. (Its value is headerLenght + 4.)
- */
- private long topFp;
-
- /**
- * The <code>BatchWriter</code> that owns this <code>BatchLog</code>.
- */
- private BatchWriter writer;
-
- /**
- * Auxiliary buffer used to fill up with null bytes the part of the file
- * that follows the header.
- */
- private ByteBuffer cleanBuffer = ByteBuffer.wrap(nulls);
-
- /**
- * Constructs a new <code>BatchLog</code>.
- *
- * @param writer the <code>BatchWriter</code> that will own
- * the new <code>BatchLog</code>
- * @param header an object to be written at the beginning of the log file
- * @param dir the directory in which the log file will be created
- * @param fileSize the fixed size of the log file
- * @throws IOException
- */
- BatchLog(BatchWriter writer, Object header, File dir, int fileSize)
- throws IOException
- {
- this.writer = writer;
- this.header = header;
- logFile = File.createTempFile("TX_RECOVERY_LOG", ".log", dir);
- os = new RandomAccessFile(logFile, "rw");
-
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- ObjectOutputStream oos = new ObjectOutputStream(baos);
- oos.writeObject(header);
- byte[] bytes = baos.toByteArray();
-
- os.setLength(fileSize);
- os.writeInt(bytes.length);
- os.write(bytes);
-
- channel = os.getChannel();
- // Force also metadata. We do this just once, as the file size is fixed.
- channel.force(true);
- topFp = channel.position();
-
- cleanUpLogFile();
- }
-
- /**
- * Gets the <code>BatchWriter</code> that owns this <code>BatchLog</code>.
- *
- * @return the <code>BatchWriter</code> that issues write calls on this
- * this <code>BatchLog</code>.
- */
- BatchWriter getBatchWriter()
- {
- return writer;
- }
-
- /**
- * Gets this <code>BatchLog</code>'s current position, which is also the
- * number of currently used bytes of its log file.
- *
- * @return the offset from the beginning of the log file, in bytes,
- * at which the next write will happen.
- * @throws IOException
- */
- int getPosition()
- throws IOException
- {
- return (int) channel.position();
- }
-
- /**
- * Gets the name of the underlying log file.
- *
- * @return the name of this <code>BatchLog</code>'s log file.
- */
- String getFilename()
- {
- return logFile.getName();
- }
-
- /**
- * Writes one record at the current position of this <code>BatchLog</code>.
- *
- * @param record a buffer with the record to be written
- * @param isEndRecord true if the record is an end record and false otherwise
- * @throws IOException
- */
- void write(ByteBuffer record, boolean isEndRecord)
- throws IOException
- {
- channel.write(record);
- if (isEndRecord)
- {
- numEndRecords++;
-
- synchronized (this)
- {
- if (markedForRestart == true &&
- numLoggedTransactions ==
- numLocalTransactionsCompleted + numEndRecords)
- {
- writer.restartBatchLog(this);
- }
- }
- }
- else
- {
- channel.force(false);
- numLoggedTransactions++;
- }
- }
-
- /**
- * Writes a sequence of records to this <code>BatchLog</code>.
- * The sequence of records is taken from the given array of buffers,
- * starting at the specified offset, and it is written at the current
- * position of this <code>BatchLog</code>.
- *
- * @param records an array of buffers containing records that should be
- * written to the log
- * @param offset the index of the first record of the <code>records</code>
- * array that should be written to the log
- * @param length the number of records that should be written to the log
- * @param numTransactionRecords specifies how many of the <code>lenght</code>
- * records are records for new transactions (commit, multi-TM
- * commit, prepare and JCA prepare records). The remaining
- * <code>length - numTransactionRecords</code> records are
- * end-of-transaction records.
- * @throws IOException
- */
- void write(ByteBuffer[] records,
- int offset,
- int length,
- int numTransactionRecords)
- throws IOException
- {
- channel.write(records, offset, length);
-
- if (numTransactionRecords > 0)
- {
- channel.force(false);
- numLoggedTransactions += numTransactionRecords;
- }
-
- if (numTransactionRecords < length)
- {
- numEndRecords += (length - numTransactionRecords);
-
- synchronized (this)
- {
- if (markedForRestart == true &&
- numLoggedTransactions ==
- numLocalTransactionsCompleted + numEndRecords)
- {
- writer.restartBatchLog(this);
- }
- }
- }
-
- }
-
- /**
- * Signals the end of the two-phase commit protocol for a committed
- * transaction that does not need an end record to be logged. This method
- * should be invoked when the second phase of the two-phase commit protocol
- * completes successfully.
- *
- * @param localTransactionId the local id of the completed transaction.
- */
- public void handleTxCompletion(long localTransactionId)
- {
- synchronized (this)
- {
- numLocalTransactionsCompleted++;
- if (markedForRestart == true &&
- numLoggedTransactions ==
- numLocalTransactionsCompleted + numEndRecords)
- {
- writer.restartBatchLog(this);
- }
- }
- }
-
- /**
- * Marks this <code>BatchLog</code> for restart. The restart will occur
- * only when there are no more outstanding transactions, i.e, when
- * <code>numLocalTransactionsCompleted + numEndRecords</code> reaches
- * <code>numLoggedTransactions</code>.
- */
- void markForRestart()
- {
- synchronized (this)
- {
- markedForRestart = true;
- if (numLoggedTransactions ==
- numLocalTransactionsCompleted + numEndRecords)
- {
- writer.restartBatchLog(this);
- }
- }
- }
-
- /**
- * Restarts this <code>BatchLog</code>. Overwrites with null bytes all
- * log records in the log file, then returns the <code>BatchLog</code>
- * to its <code>BatchWriter</code>s pool of clean <code>BatchLog</code>
- * instances.
- * <p>
- * Only the <code>LogRestarter</code> calls this method.
- *
- * @throws IOException
- */
- void restart()
- throws IOException
- {
- // TODO may have to rewrite header when we start recording XAResource
- // handles in it as a new one may be deployed/undeployed
- channel.position(topFp);
- cleanUpLogFile();
- writer.getNextLogs().add(this);
- }
-
- /**
- * Overwrites with null bytes all log records in the log file, without
- * changing the size of the file.
- */
- void cleanUpLogFile()
- throws IOException
- {
- numLoggedTransactions = 0;
- numLocalTransactionsCompleted = 0;
- numEndRecords = 0;
- markedForRestart = false;
-
- // Overwites the remainder of the log file with null bytes.
- cleanBuffer.limit(cleanBuffer.capacity());
- while (channel.position() <= channel.size() - cleanBuffer.limit())
- {
- cleanBuffer.rewind();
- channel.write(cleanBuffer);
- }
- cleanBuffer.limit((int) (channel.size() - channel.position()));
- cleanBuffer.rewind();
- channel.write(cleanBuffer);
- channel.force(false);
-
- channel.position(topFp);
- }
-
- /**
- * Closes this <code>BatchLog</code>. If there are no outstanding
- * transactions then all log records in the log file are erased.
- */
- void close()
- {
- errorLog.info("Closing transaction log " + getFilename() +
- ", numLoggedTransactions=" + numLoggedTransactions +
- ", numLocalTransactionsCompleted=" +
- numLocalTransactionsCompleted +
- ", numEndRecords=" + numEndRecords);
- try
- {
- if (numLoggedTransactions ==
- numLocalTransactionsCompleted + numEndRecords)
- {
- channel.position(topFp);
- channel.truncate(topFp);
- }
- os.close();
- }
- catch (IOException e)
- {
- errorLog.error("Error closing transaction log " + getFilename(), e);
- }
- }
-
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/recovery/BatchRecoveryLogReader.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/recovery/BatchRecoveryLogReader.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/recovery/BatchRecoveryLogReader.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,454 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.recovery;
-
-import java.io.ByteArrayInputStream;
-import java.io.DataInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.RandomAccessFile;
-import java.nio.ByteBuffer;
-import java.nio.channels.FileChannel;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.jboss.logging.Logger;
-import org.jboss.tm.XidFactoryBase;
-
-/**
- * Simple implementation of <code>RecoveryLogReader</code> used at recovery
- * time. The <code>BatchRecoveryLogger</code>'s implementation of method
- * <code>getRecoveryLogs()</code> instantiates
- * <code>BatchRecoveryLogReader</code>s for the existing recovery log files.
- * It returns an array containing those readers, which the recovery manager
- * uses to get the information in the log files.
- *
- * @author <a href="mailto:bill at jboss.org">Bill Burke</a>
- * @author <a href="mailto:reverbel at ime.usp.br">Francisco Reverbel</a>
- * @version $Revision$
- */
-class BatchRecoveryLogReader
- implements RecoveryLogReader
-
-{
- /** Class <code>Logger</code>, for trace messages. */
- private static Logger errorLog =
- Logger.getLogger(BatchRecoveryLogReader.class);
-
- /** The log file read by this reader. */
- private File logFile;
-
- /** Xid factory for converting local transaction ids into global ids. */
- private XidFactoryBase xidFactory;
-
- /**
- * Constructs a <code>BatchRecoveryLogReader</code>.
- *
- * @param logFile the log file that will be read by the reader
- * @param xidFactory Xid factory that the reader will use to convert local
- * transaction ids into global ids.
- */
- BatchRecoveryLogReader(File logFile, XidFactoryBase xidFactory)
- {
- this.logFile = logFile;
- this.xidFactory = xidFactory;
- }
-
- /**
- * Reads the header object written out to the beginning of the log file via
- * Java serialization.
- *
- * @param dis a <code>DataInputStream</code> view of the log file
- * @return the header object read from the log file.
- * @throws IOException if there is an error reading the header object
- * @throws ClassNotFoundException if the class of the header object is not
- * available.
- */
- private Object readHeaderObject(DataInputStream dis)
- throws IOException,
- ClassNotFoundException
- {
- int num = dis.readInt();
- byte[] bytes = new byte[num];
- dis.read(bytes);
- ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
- ObjectInputStream ois = new ObjectInputStream(bais);
- return ois.readObject();
- }
-
- // RecoveryLogReader implementation ------------------------------
-
- /**
- * Gets the name of the underlying log file.
- *
- * @return the name of the log file.
- */
- public String getLogFileName()
- {
- return logFile.toString();
- }
-
- /**
- * Gets the branch qualifier string stored in the log file header.
- *
- * @return the branch qualifier read from the log file header.
- */
- public String getBranchQualifier()
- {
- FileInputStream fis;
- DataInputStream dis;
-
- try
- {
- fis = new FileInputStream(logFile);
- dis = new DataInputStream(fis);
- try
- {
- return (String) readHeaderObject(dis);
- }
- finally
- {
- fis.close();
- }
- }
- catch (Exception e)
- {
- throw new RuntimeException(e);
- }
- }
-
- /**
- * Recovers transaction information from the log file.
- *
- * @param committedSingleTmTransactions a <code>List</code> of
- * <code>LogRecord.Data</code> instances with one element per
- * committed single-TM transaction logged to the log file
- * @param committedMultiTmTransactions a <code>List</code> of
- * <code>LogRecord.Data</code> instances with one element per
- * committed multi-TM transaction that has not yet completed the
- * second phase of the 2PC protocol when the server crashed
- * @param inDoubtTransactions a <code>List</code> of
- * <code>LogRecord.Data</code> instances with one element per
- * foreign transaction that arrived at the server via DTM/OTS
- * context propagation and was in the in-doubt state (i.e.,
- * replied to prepare with a commit vote but has not yet received
- * information on the transaction outcome) when the server crashed
- * @param inDoubtJcaTransactions a <code>List</code> of
- * <code>LogRecord.Data</code> instances with one element per
- * foreign transaction that arrived at the server via JCA
- * transaction inflow and was in the in-doubt state (i.e., replied
- * to prepare with a commit vote and was waiting for information
- * on the transaction outcome) when the server crashed.
- */
- public void recover(List committedSingleTmTransactions,
- List committedMultiTmTransactions,
- List inDoubtTransactions,
- List inDoubtJcaTransactions)
- {
- Map activeMultiTmTransactions = new HashMap();
- FileInputStream fis;
- DataInputStream dis;
- CorruptedLogRecordException corruptedLogRecordException = null;
-
- try
- {
- fis = new FileInputStream(logFile);
- dis = new DataInputStream(fis);
-
- }
- catch (IOException e)
- {
- throw new RuntimeException(e);
- }
-
- try
- {
- readHeaderObject(dis); // branch qualifier
-
- if (fis.available() < LogRecord.FULL_HEADER_LEN)
- return;
-
- FileChannel channel = fis.getChannel();
- ByteBuffer buf = ByteBuffer.allocate(LogRecord.FULL_HEADER_LEN);
- channel.read(buf);
-
- LogRecord.Data data;
- int len = LogRecord.getNextRecordLength(buf, 0);
-
- while (len > 0)
- {
- buf = ByteBuffer.allocate(len + LogRecord.FULL_HEADER_LEN);
- if (channel.read(buf) < len)
- {
- errorLog.info("Unexpected end of file in transaction log file " +
- logFile.getName());
- break;
- }
- buf.flip();
- data = new LogRecord.Data();
- try
- {
- LogRecord.getData(buf, len, data);
- }
- catch (CorruptedLogRecordException e)
- {
- // Save the exception only if no previous exception is saved.
- if (corruptedLogRecordException == null)
- corruptedLogRecordException = e;
- long corruptedRecordPos =
- channel.position() - buf.limit() - LogRecord.FULL_HEADER_LEN;
- long nextPos = scanForward(corruptedRecordPos + 1);
- if (nextPos == 0)
- {
- errorLog.info("LOG CORRUPTION AT THE END OF LOG FILE " +
- logFile.getName());
- break;
- }
- else
- {
- errorLog.info("LOG CORRUPTION IN THE MIDDLE OF LOG FILE " +
- logFile.getName() + ". Skipping " +
- (nextPos - corruptedRecordPos) + " bytes" +
- ". Disabling presumed rollback.");
- channel.position(nextPos);
- buf = ByteBuffer.allocate(LogRecord.FULL_HEADER_LEN);
- channel.read(buf);
- len = LogRecord.getNextRecordLength(buf, 0);
- corruptedLogRecordException.disablePresumedRollback = true;
- continue;
- }
- }
- switch (data.recordType)
- {
- case LogRecord.TX_COMMITTED:
- data.globalTransactionId =
- xidFactory.localIdToGlobalId(data.localTransactionId);
- committedSingleTmTransactions.add(data);
- break;
- case LogRecord.MULTI_TM_TX_COMMITTED:
- data.globalTransactionId =
- xidFactory.localIdToGlobalId(data.localTransactionId);
- // fall through
- case LogRecord.TX_PREPARED:
- case LogRecord.JCA_TX_PREPARED:
- activeMultiTmTransactions.put(new Long(data.localTransactionId),
- data);
- break;
- case LogRecord.TX_END:
- activeMultiTmTransactions.remove(
- new Long(data.localTransactionId));
- break;
- default:
- errorLog.warn("INVALID TYPE IN LOG RECORD.");
- break;
- }
- try
- {
- len = LogRecord.getNextRecordLength(buf, len);
- }
- catch (CorruptedLogRecordException e)
- {
- // Save the exception only if no previous exception is saved.
- if (corruptedLogRecordException == null)
- corruptedLogRecordException = e;
- long corruptedRecordPos =
- channel.position() - buf.limit() - LogRecord.FULL_HEADER_LEN;
- long nextPos = scanForward(corruptedRecordPos + 1);
- if (nextPos == 0)
- {
- errorLog.info("LOG CORRUPTION AT THE END OF LOG FILE " +
- logFile.getName());
- len = 0;
- }
- else
- {
- errorLog.info("LOG CORRUPTION IN THE MIDDLE OF LOG FILE " +
- logFile.getName() + ". Skipping " +
- (nextPos - corruptedRecordPos) + " bytes" +
- ". Disabling presumed rollback.");
- channel.position(nextPos);
- buf = ByteBuffer.allocate(LogRecord.FULL_HEADER_LEN);
- channel.read(buf);
- len = LogRecord.getNextRecordLength(buf, 0);
- corruptedLogRecordException.disablePresumedRollback = true;
- }
- }
- }
-
- Iterator iter = activeMultiTmTransactions.values().iterator();
- while (iter.hasNext())
- {
- data = (LogRecord.Data) iter.next();
-
- switch (data.recordType)
- {
- case LogRecord.MULTI_TM_TX_COMMITTED:
- committedMultiTmTransactions.add(data);
- break;
- case LogRecord.TX_PREPARED:
- inDoubtTransactions.add(data);
- break;
- case LogRecord.JCA_TX_PREPARED:
- inDoubtJcaTransactions.add(data);
- break;
- default:
- errorLog.warn("INCONSISTENT STATE.");
- break;
- }
- }
-
- if (corruptedLogRecordException != null)
- throw corruptedLogRecordException;
- }
- catch (IOException e)
- {
- errorLog.warn("Unexpected exception in recover:", e);
- }
- catch (ClassNotFoundException e)
- {
- errorLog.warn("Unexpected exception in recover:", e);
- }
- try
- {
- fis.close();
- }
- catch (IOException e)
- {
- throw new RuntimeException(e);
- }
- }
-
- /**
- * Removes the log file.
- */
- public void finishRecovery()
- {
- logFile.delete();
- }
-
- /**
- * Scans the log file for a valid log record. This is a helper method for
- * log file corruption handling.
- *
- * @param pos the file position where the forward scan should start.
- * @return the file position in which a valid log record was found, or
- * 0 if end of file was reached and no valid log record was found.
- */
- private long scanForward(long pos)
- {
- errorLog.trace("entering scanForward");
- RandomAccessFile file = null;
-
- try
- {
- file = new RandomAccessFile(logFile, "r");
-
- while (pos + LogRecord.FULL_HEADER_LEN < logFile.length())
- {
- if (match(file, pos, LogRecord.HEADER))
- {
- errorLog.trace("scanForward: match at pos=" + pos);
- file.seek(pos + LogRecord.HEADER_LEN);
- short recLen = file.readShort();
- errorLog.trace("scanForward: recLen=" + recLen);
- if (pos + LogRecord.FULL_HEADER_LEN + recLen < logFile.length())
- {
- byte[] buf = new byte[recLen];
- file.seek(pos + LogRecord.FULL_HEADER_LEN);
- file.read(buf, 0, recLen);
- if (LogRecord.hasValidChecksum(buf))
- {
- errorLog.trace("scanForward: returning " + pos);
- return pos;
- }
- else
- {
- errorLog.trace("scanForward: " +
- "bad checksum in record at pos=" + pos);
- pos += LogRecord.HEADER_LEN;
- }
- }
- else
- pos =+ LogRecord.HEADER_LEN;
- }
- else
- pos++;
- }
- errorLog.trace("scanForward: returning 0");
- return 0;
- }
- catch (FileNotFoundException e)
- {
- errorLog.warn("Unexpected exception in scanForward:", e);
- return 0;
- }
- catch (IOException e)
- {
- errorLog.warn("Unexpected exception in scanForward:", e);
- return 0;
- }
- finally
- {
- if (file != null)
- {
- try
- {
- file.close();
- }
- catch (IOException e)
- {
- errorLog.warn("Unexpected exception in scanForward:", e);
- }
- }
- }
- }
-
- /**
- * Returns true if the byte sequence that starts at given position of a
- * file matches a given byte array.
- *
- * @param file a random access file open for reading
- * @param pos the file position of the byte sequence to be compared against
- * the <code>pattern</code> byte array
- * @param pattern the byte pattern to match.
- * @return true if the pattern appears at the specified position of the
- * file, and false otherwise/
- * @throws IOException if there is a problem reading the file.
- */
- private static boolean match(RandomAccessFile file, long pos, byte[] pattern)
- throws IOException
- {
- for (int i = 0; i < pattern.length; i++)
- {
- file.seek(pos + i);
- if (file.readByte() != pattern[i])
- return false;
- }
- return true;
- }
-
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/recovery/BatchRecoveryLogger.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/recovery/BatchRecoveryLogger.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/recovery/BatchRecoveryLogger.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,403 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.recovery;
-
-import java.io.File;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-
-import javax.transaction.xa.Xid;
-
-import org.jboss.tm.XidFactoryBase;
-
-/**
- * This <code>RecoveryLogger</code> implementation
- * uses <code>BatchWriter</code>s that batch log write requests
- * in order to minimize disk forcing activity. A
- * <code>BatchRecoveryLogger</code> instance is the "main object" of the
- * the recovery logger service, which is simply an MBean wrapper for that
- * instance.
- *
- * @author <a href="mailto:bill at jboss.org">Bill Burke</a>
- * @author <a href="mailto:reverbel at ime.usp.br">Francisco Reverbel</a>
- * @version $Revision$
- */
-public class BatchRecoveryLogger
- implements RecoveryLogger
-{
- /** Array of names of directories that contain recovery log files. */
- private String[] stringDirectoryList;
-
- /** Array of directories that contain recovery log files. */
- private File[] directoryList;
-
- /** The constant size of a recovery log file. */
- private int logFileSize;
-
- /** Array of recovery log files found at recovery time. */
- private File[] existingRecoveryLogFiles;
-
- /** Array of log writers (one per directory that contains log files). */
- private BatchWriter[] writers;
-
- /** Number of log writers (number of directories that contain log files). */
- private int numWriters;
-
- /** Sequential number used to choose a log writer */
- private volatile int seqNo = 0;
-
- /** Name of the directory that contains heuristic status log files. */
- private String heuristicStatusLogDirectoryName;
-
- /** Directory that contain heuristic status log files. */
- private File heuristicStatusLogDirectory;
-
- /** Array of heuristic status log files found at recovery time. */
- private File[] existingHeuristicStatusLogFiles;
-
- /** Heuristic status log writer. */
- private HeuristicStatusLog heuristicStatusLogger;
-
- /** The server's Xid factory. */
- private XidFactoryBase xidFactory;
-
- /** For asynchronously restarting <code>BatchLog</code> instances. */
- private LogRestarter logCleaner;
-
- // Package protected methods -------------------------------------
- // (The BatchRecoveryLoggerService calls these methods.)
-
- /*
- * Gets the names of directories that contain recovery log files.
- *
- * @return an array of names of directories that contain recovery log
- * files.
- *
- */
- String[] getDirectoryList()
- {
- return stringDirectoryList;
- }
-
- /**
- * Sets the names of directories that contain recovery log files.
- * <p />
- * This method used to be package protected. It was changed to public just
- * for testing purposes.
- *
- * @param directoryList array of names of directories that contain recovery
- * log files.
- *
- */
- public void setDirectoryList(String[] directoryList)
- {
- this.stringDirectoryList = directoryList;
- File[] list = new File[directoryList.length];
- for (int i = 0; i < directoryList.length; i++)
- {
- list[i] = new File(directoryList[i]);
- list[i] = list[i].getAbsoluteFile();
- if (!list[i].exists())
- {
- if (!list[i].mkdirs())
- {
- throw new RuntimeException("Unable to create recovery directory: "
- + directoryList[i]);
- }
- }
- }
- this.directoryList = list;
- }
-
- /**
- * Gets the constant size of a log file.
- *
- * @return the constans size of a log file, in bytes.
- */
- int getLogFileSize()
- {
- return logFileSize;
- }
-
- /**
- * Sets the constant size of a log file.
- * <p />
- * This method used to be package protected. It was changed to public just
- * for testing purposes.
- *
- * @param logFileSize the constant size of a log file, in bytes.
- */
- public void setLogFileSize(int logFileSize)
- {
- this.logFileSize = logFileSize;
- }
-
- /**
- * Gets the name of the directory that contains heuristic status log files.
- *
- * @return the name of the directory that contains heuristic status log
- * files.
- */
- String getHeuristicStatusLogDirectory()
- {
- return heuristicStatusLogDirectoryName;
- }
-
- /**
- * Sets the name of the directory that contains heuristic status log files.
- * <p />
- * This method used to be package protected. It was changed to public just
- * for testing purposes.
- *
- * @param heuristicStatusLogDirectoryName the name of the directory that
- * contains heuristic status log files.
- */
- public void setHeuristicStatusLogDirectory(String heuristicStatusLogDirectoryName)
- {
- this.heuristicStatusLogDirectoryName = heuristicStatusLogDirectoryName;
- heuristicStatusLogDirectory = new File(heuristicStatusLogDirectoryName);
- heuristicStatusLogDirectory =
- heuristicStatusLogDirectory.getAbsoluteFile();
- if (!heuristicStatusLogDirectory.exists())
- {
- if (!heuristicStatusLogDirectory.mkdirs())
- {
- throw new RuntimeException("Unable to create heuristic status " +
- "log directory: "
- + heuristicStatusLogDirectoryName);
- }
- }
- }
-
- /**
- * Gets the Xid factory.
- *
- * @return the Xid factory.
- */
- XidFactoryBase getXidFactory()
- {
- return xidFactory;
- }
-
- /**
- * Sets the Xid factory
- * <p />
- * This method used to be package protected. It was changed to public just
- * for testing purposes.
- *
- * @param xidFactory the Xid factory.
- */
- public void setXidFactory(XidFactoryBase xidFactory)
- {
- this.xidFactory = xidFactory;
- }
-
- /**
- * Starts this <code>BatchRecoveryLoggger</code>.
- * <p />
- * This method used to be package protected. It was changed to public just
- * for testing purposes.
- */
- public void start() throws Exception
- {
- ArrayList list = new ArrayList();
- for (int i = 0; i < directoryList.length; i++)
- {
- File dir = directoryList[i];
- File[] files = dir.listFiles();
- for (int j = 0; j < files.length; j++)
- {
- list.add(files[j]);
- }
- }
- existingRecoveryLogFiles = (File[]) list.toArray(new File[list.size()]);
-
- logCleaner = new LogRestarter();
- new Thread(logCleaner, "Log file cleaner").start();
-
- writers = new BatchWriter[directoryList.length];
- String branchQualifier = xidFactory.getBranchQualifier();
- for (int i = 0; i < directoryList.length; i++)
- {
- writers[i] = new BatchWriter(branchQualifier, logFileSize / 128,
- directoryList[i], logFileSize, logCleaner);
- new Thread(writers[i], "Batch Recovery Log " + i).start();
- }
- numWriters = writers.length;
-
- existingHeuristicStatusLogFiles = heuristicStatusLogDirectory.listFiles();
- heuristicStatusLogger =
- new HeuristicStatusLog(heuristicStatusLogDirectory);
- }
-
- /**
- * Stops this <code>BatchRecoveryLoggger</code>.
- * <p />
- * This method used to be package protected. It was changed to public just
- * for testing purposes.
- */
- public void stop() throws Exception
- {
- for (int i = 0; i < writers.length; i++)
- {
- writers[i].stop();
- }
- logCleaner.stop();
- heuristicStatusLogger.close();
- }
-
- // RecoveryLogger implementation ---------------------------------
-
- /**
- * @see org.jboss.tm.recovery.RecoveryLogger#saveCommitDecision(
- * long, java.lang.String[])
- */
- public TxCompletionHandler saveCommitDecision(long localTransactionId,
- String[] resources)
- {
- ByteBuffer buffer;
-
- if (resources == null || resources.length == 0)
- {
- buffer = LogRecord.createTxCommittedRecord(localTransactionId);
- return writers[++seqNo % numWriters].addBatch(buffer, false);
- }
- else
- {
- buffer = LogRecord.createTxCommittedRecord(localTransactionId,
- resources);
- return writers[++seqNo % numWriters].addBatch(buffer, true);
- }
- }
-
- /**
- * @see org.jboss.tm.recovery.RecoveryLogger#savePrepareDecision(
- * long, int, byte[], java.lang.String, java.lang.String[])
- */
- public TxCompletionHandler savePrepareDecision(long localTransactionId,
- int inboundFormatId,
- byte[] globalTransactionId,
- String recoveryCoordinator,
- String[] resources)
- {
- ByteBuffer buffer = LogRecord.createTxPreparedRecord(localTransactionId,
- inboundFormatId,
- globalTransactionId,
- recoveryCoordinator,
- resources);
- return writers[++seqNo % numWriters].addBatch(buffer, true);
- }
-
- /**
- * @see org.jboss.tm.recovery.RecoveryLogger#savePrepareDecision(
- * long, javax.transaction.xa.Xid, java.lang.String[])
- */
- public TxCompletionHandler savePrepareDecision(long localTransactionId,
- Xid inboundXid,
- String[] resources)
- {
- ByteBuffer buffer =
- LogRecord.createJcaTxPreparedRecord(localTransactionId,
- inboundXid,
- resources);
- return writers[++seqNo % numWriters].addBatch(buffer, true);
- }
-
- /**
- * @see org.jboss.tm.recovery.RecoveryLogger#saveHeuristicStatus(
- * long, boolean, int, byte[], byte[], int, int, boolean int[],
- * org.jboss.tm.recovery.HeuristicStatus[])
- */
- public void saveHeuristicStatus(long localTransactionId,
- boolean foreignTx,
- int formatId,
- byte[] globalTransactionId,
- byte[] inboundBranchQualifier,
- int transactionStatus,
- int heurStatusCode,
- boolean locallyDetectedHeuristicHazard,
- int[] xaResourceHeuristics,
- HeuristicStatus[] remoteResourceHeuristics)
- {
- ByteBuffer buffer =
- LogRecord.createHeurStatusRecord(localTransactionId,
- foreignTx,
- formatId,
- globalTransactionId,
- inboundBranchQualifier,
- transactionStatus,
- heurStatusCode,
- locallyDetectedHeuristicHazard,
- xaResourceHeuristics,
- remoteResourceHeuristics);
- heuristicStatusLogger.write(buffer);
- }
-
- /**
- * @see org.jboss.tm.recovery.RecoveryLogger#clearHeuristicStatus(long)
- */
- public void clearHeuristicStatus(long localTransactionId)
- {
- ByteBuffer buffer =
- LogRecord.createHeurForgottenRecord(localTransactionId);
- heuristicStatusLogger.write(buffer);
- }
-
- /**
- * @see org.jboss.tm.recovery.RecoveryLogger#getRecoveryLogs()
- */
- public RecoveryLogReader[] getRecoveryLogs()
- {
- if (existingRecoveryLogFiles == null
- || existingRecoveryLogFiles.length == 0)
- return null;
-
- RecoveryLogReader[] readers =
- new RecoveryLogReader[existingRecoveryLogFiles.length];
- for (int i = 0; i < readers.length; i++)
- {
- readers[i] =
- new BatchRecoveryLogReader(existingRecoveryLogFiles[i], xidFactory);
- }
- return readers;
- }
-
- /**
- * @see org.jboss.tm.recovery.RecoveryLogger#getHeuristicStatusLogs()
- */
- public HeuristicStatusLogReader[] getHeuristicStatusLogs()
- {
- if (existingHeuristicStatusLogFiles == null
- || existingHeuristicStatusLogFiles.length == 0)
- return null;
-
- HeuristicStatusLogReader[] readers =
- new HeuristicStatusLogReader[existingHeuristicStatusLogFiles.length];
- for (int i = 0; i < readers.length; i++)
- {
- readers[i] = new SimpleHeuristicStatusLogReader(
- existingHeuristicStatusLogFiles[i]);
- }
- return readers;
- }
-
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/recovery/BatchRecoveryLoggerService.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/recovery/BatchRecoveryLoggerService.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/recovery/BatchRecoveryLoggerService.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,167 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.recovery;
-
-import javax.management.ObjectName;
-
-import org.jboss.system.ServiceMBeanSupport;
-import org.jboss.tm.XidFactoryMBean;
-
-/**
- * Service MBean that provides recovery logger functionality. The
- * <code>BatchRecoveryLoggerService</code> is simply an MBean wrapper for a
- * <code>BatchRecoveryLogger</code> instance, which does the real work.
- *
- * @author <a href="mailto:bill at jboss.org">Bill Burke</a>
- * @version $Revision$
- */
-public class BatchRecoveryLoggerService
- extends ServiceMBeanSupport
- implements BatchRecoveryLoggerServiceMBean
-{
- /** The actual recovery logger. */
- protected BatchRecoveryLogger logger;
-
- /** The recovery logger's Xid factory. */
- private ObjectName xidFactory;
-
- /**
- * Constructs a <code>BatchRecoveryLoggerService</code>.
- */
- public BatchRecoveryLoggerService()
- {
- logger = createLogger();
- }
-
- /**
- * To be overrided by subclasses that create a logger derived from
- * <code>BatchRecoveryLogger</code> for testing purposes.
- */
- protected BatchRecoveryLogger createLogger()
- {
- return new BatchRecoveryLogger();
- }
-
- // ServiceMBeanSupport overrides ---------------------------------
-
- /**
- * @see org.jboss.system.ServiceMBeanSupport#startService()
- */
- public void startService() throws Exception
- {
- super.startService();
- XidFactoryMBean xidFactoryObj =
- (XidFactoryMBean) getServer().getAttribute(xidFactory, "Instance");
- logger.setXidFactory(xidFactoryObj);
- logger.start();
- }
-
- /**
- * @see org.jboss.system.ServiceMBeanSupport#stopService()
- */
- public void stopService() throws Exception
- {
- super.stopService();
- logger.stop();
- }
-
- // RecoveryLoggerInstance implementation -------------------------
-
- /**
- * @see org.jboss.tm.recovery.RecoveryLoggerInstance#getInstance()
- */
- public RecoveryLogger getInstance()
- {
- return logger;
- }
-
- // BatchRecoveryLoggerServiceMBean implementation ----------------
-
- /**
- * @see org.jboss.tm.recovery.BatchRecoveryLoggerServiceMBean#getDirectoryList()
- */
- public String[] getDirectoryList()
- {
- return logger.getDirectoryList();
- }
-
- /**
- * @see org.jboss.tm.recovery.BatchRecoveryLoggerServiceMBean#setDirectoryList(
- * java.lang.String[])
- */
- public void setDirectoryList(String[] directoryList)
- {
- logger.setDirectoryList(directoryList);
- }
-
- /**
- * @see org.jboss.tm.recovery.BatchRecoveryLoggerServiceMBean#getLogFileSize()
- */
- public int getLogFileSize()
- {
- return logger.getLogFileSize();
- }
-
- /**
- * @see org.jboss.tm.recovery.BatchRecoveryLoggerServiceMBean#setLogFileSize(
- * int)
- */
- public void setLogFileSize(int logFileSize)
- {
- logger.setLogFileSize(logFileSize);
- }
-
- /**
- * @see org.jboss.tm.recovery.BatchRecoveryLoggerServiceMBean#getHeuristicStatusLogDirectory()
- */
- public String getHeuristicStatusLogDirectory()
- {
- return logger.getHeuristicStatusLogDirectory();
- }
-
- /**
- * @see org.jboss.tm.recovery.BatchRecoveryLoggerServiceMBean#setHeuristicStatusLogDirectory(
- * java.lang.String)
- */
- public void setHeuristicStatusLogDirectory(String directory)
- {
- logger.setHeuristicStatusLogDirectory(directory);
- }
-
- /**
- * @see org.jboss.tm.recovery.BatchRecoveryLoggerServiceMBean#getXidFactory()
- */
- public ObjectName getXidFactory()
- {
- return xidFactory;
- }
-
- /**
- * @see org.jboss.tm.recovery.BatchRecoveryLoggerServiceMBean#setXidFactory(
- * javax.management.ObjectName)
- */
- public void setXidFactory(ObjectName xidFactory)
- {
- this.xidFactory = xidFactory;
- }
-
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/recovery/BatchRecoveryLoggerServiceMBean.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/recovery/BatchRecoveryLoggerServiceMBean.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/recovery/BatchRecoveryLoggerServiceMBean.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,100 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.recovery;
-
-import javax.management.ObjectName;
-
-import org.jboss.system.ServiceMBean;
-
-/**
- * MBean interface of the batch recovery logger service.
- *
- * @author <a href="mailto:bill at jboss.org">Bill Burke</a>
- * @version $Revision$
- */
-public interface BatchRecoveryLoggerServiceMBean
- extends RecoveryLoggerInstance,
- ServiceMBean
-{
- /*
- * Gets the names of directories that contain recovery log files.
- *
- * @return an array of names of directories that contain recovery log
- * files.
- *
- */
- String[] getDirectoryList();
-
- /**
- * Sets the names of directories that contain recovery log files.
- *
- * @param directoryList array of names of directories that contain recovery
- * log files.
- *
- */
- void setDirectoryList(String[] directoryList);
-
- /**
- * Gets the constant size of a log file.
- *
- * @return the constans size of a log file, in bytes.
- */
- int getLogFileSize();
-
- /**
- * Sets the constant size of a log file.
- *
- * @param logFileSize the constant size of a log file, in bytes.
- */
- void setLogFileSize(int logFileSize);
-
- /**
- * Gets the name of the directory that contains heuristic status log files.
- *
- * @return the name of the directory that contains heuristic status log
- * files.
- */
- String getHeuristicStatusLogDirectory();
-
- /**
- * Sets the name of the directory that contains heuristic status log files.
- *
- * @param heuristicStatusLogDirectoryName the name of the directory that
- * contains heuristic status log files.
- */
- void setHeuristicStatusLogDirectory(String directory);
-
- /**
- * Gets the Xid factory.
- *
- * @return the Xid factory.
- */
- ObjectName getXidFactory();
-
- /**
- * Sets the Xid factory
- *
- * @param xidFactory the Xid factory.
- */
- void setXidFactory(ObjectName xidFactory);
-
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/recovery/BatchWriter.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/recovery/BatchWriter.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/recovery/BatchWriter.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,469 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.recovery;
-
-import EDU.oswego.cs.dl.util.concurrent.Latch;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import org.jboss.logging.Logger;
-
-/**
- * This class batches log write requests in order to minimize disk forcing
- * activity. A <code>BatchWriter</code> has a current <code>BatchLog</code>
- * instance, to which it writes log records, plus a pool of clean
- * <code>BatchLog</code> instances, to be used when the current
- * <code>BatchLog</code> gets full. It maintains a queue of write requests
- * and implements a writer thread that takes write requests from the queue
- * and batches them together in order to minimize disk forces.
- * <p>
- * The <code>BatchLog</code> instances owned by a <code>BatchWriter</code>
- * know their owner <code>BatchWriter</code> and call the methods
- * <code>restartBatchLog</code> and <code>getNextLogs</code> on their owner.
- *
- * @author <a href="mailto:bill at jboss.org">Bill Burke</a>
- * @author <a href="mailto:reverbel at ime.usp.br">Francisco Reverbel</a>
- * @version $Revision$
- */
-class BatchWriter implements Runnable
-{
-
- /** Class <code>Logger</code> for trace messages. */
- private static Logger errorLog = Logger.getLogger(BatchWriter.class);
-
- /** True if trace messages should be logged. */
- private static boolean traceEnabled = errorLog.isTraceEnabled();
-
- /** The directory in which log files will be created. */
- private final File dir;
-
- /** The initial capacity of the queue of write requests. */
- private final int initialCapacity;
-
- /** The current <code>BatchLog</code> instance. */
- private BatchLog log;
-
- /** The constant size of a recovery log file. */
- private final int fileSize;
-
- /** The header object written to the beginning of a log file. */
- private Object header;
-
- /** Exception thrown when switching the current log file. */
- private Exception abort;
-
- /** This flag can be set to false to stop the writer thread. */
- private boolean running = true;
-
- /** Pool of clean <code>BatchLog</code> instances. */
- private final List nextLogs = Collections.synchronizedList(new ArrayList());
-
- /** Synchronizes accesses to the <code>currentQueue</code> of requests. */
- private Object batchLock = new Object();
-
- /** The current queue of write requests */
- private ArrayList currentQueue;
-
- /** Latch released when a batch of write requests are performed. */
- private Latch currentLatch;
-
- /** For asynchronously restarting <code>BatchLog</code> instances. */
- private LogRestarter logRestarter;
-
- /**
- * Constructs a <code>BatchWriter</code>.
- *
- * @param header the header object to be placed at the beginning of the
- * <code>BatchLog</code>s owned by this
- * <code>BatchWriter</code>
- * @param initialCapacity the initial capacity (in bytes) of the queue of
- * write requests
- * @param dir the directory in which log files will be created
- * @param fileSize the constant size (in bytes) of a log file
- * @param logRestarter <code>LogRestarter</code> instance that the
- * <code>BatchWriter</code> will use for asynchronously
- * restarting <code>BatchLog</code> instances.
- * @throws IOException if a log file could not be created or initialized.
- */
- BatchWriter(Object header, int initialCapacity,
- File dir, int fileSize, LogRestarter logRestarter)
- throws IOException
- {
- this.header = header;
- this.fileSize = fileSize;
- this.initialCapacity = initialCapacity;
- this.currentQueue = new ArrayList(initialCapacity);
- this.currentLatch = new Latch();
- this.dir = dir;
- this.logRestarter = logRestarter;
- log = new BatchLog(this, header, dir, fileSize);
- nextLogs.add(new BatchLog(this, header, dir, fileSize));
- }
-
- /**
- * Asynchronously restarts a given <code>BatchLog</code>. The
- * <code>BatchLog</code> instances owned by this <code>BatchWriter</code>
- * call this method to asynchronously restart themselves.
- *
- * @param logToRestart the <code>BatchLog</code> to be asynchronously
- * restarted.
- */
- void restartBatchLog(BatchLog logToRestart)
- {
- logRestarter.add(logToRestart);
- }
-
- /**
- * Gets the <code>List</code> that implements the pool of clean
- * <code>BatchLog</code> instances of this <code>BatchWriter</code>.
- * The <code>BatchLog</code> instances owned by this
- * <code>BatchWriter</code> call this method after clean up, to add
- * themselves to pool of clean <code>BatchLog</code> instances.
- *
- * @return the <code>List</code> of clean <code>BatchLog</code> instances
- * kept by this <code>BatchWriter</code>.
- */
- List getNextLogs()
- {
- return nextLogs;
- }
-
- // FIXME: nobody calls this method
- void clearAbort()
- {
- abort = null;
- }
-
- /**
- * Stops the writer thread.
- */
- void stop()
- {
- synchronized (batchLock)
- {
- running = false;
- batchLock.notifyAll();
- }
- }
-
- /**
- * Force-writes a "transaction committed" or "transaction prepared" log
- * record to the current <code>BatchLog</code>.
- *
- * @param buffer a <code>ByteBuffer</code> containing a log record to
- * be written to the current <code>BatchLog</code>
- * @param expectEndRecord true if the log record requires another log record
- * (a <code>TX_END</code> record) to be eventually written
- * to the same <code>BatchLog</code>.
- * @return a <code>TxCompletionHandler</code> that should be invoked at the
- * end of the second phase of the two-phase commit protocol
- * for the transaction that generated the log record.
- */
- TxCompletionHandler addBatch(ByteBuffer buffer, boolean expectEndRecord)
- {
- PendingWriteRequest request = null;
-
- if (traceEnabled)
- {
- errorLog.trace("Transaction log record:" +
- HexDump.fromBuffer(buffer.array()));
- errorLog.trace(LogRecord.toString(buffer));
- }
-
- synchronized (batchLock)
- {
- request = new PendingWriteRequest(buffer,
- currentLatch,
- expectEndRecord);
- currentQueue.add(request);
- batchLock.notify();
- }
-
- TxCompletionHandler completionHandler = request.waitTilDone();
-
- if (!expectEndRecord)
- return completionHandler;
- else
- return new TransactionCompletionLogger((BatchLog) completionHandler);
- }
-
- /**
- * Writes a "transaction completed" (<code>TX_END</code>) record to the
- * specified <code>BatchLog</code>. Each <code>TX_END</code> record is
- * paired with a "transaction committed" or with a "transaction prepared"
- * record and should be written to the same <code>BatchLog</code> as the
- * record it is paired with. This method does not necessarily force the
- * <code>TX_END</code> record to disk, but it might do so if that record
- * is batched together with other records, which may require a forced
- * write.
- *
- * @param buffer a <code>ByteBuffer</code> containing a <code>TX_END</code>
- * record to be written to a given <code>BatchLog</code>
- * @param destinationLog the <code>BatchLog</code> to which the
- * <code>TX_END</code> record will be written.
- */
- void addBatch(ByteBuffer buffer, BatchLog destinationLog)
- {
- PendingWriteRequest receipt = null;
-
- if (traceEnabled)
- {
- errorLog.trace("Transaction Log record:" +
- HexDump.fromBuffer(buffer.array()));
- errorLog.trace(LogRecord.toString(buffer));
- }
-
- synchronized (batchLock)
- {
- receipt = new PendingWriteRequest(buffer,
- currentLatch,
- destinationLog);
- currentQueue.add(receipt);
- batchLock.notify();
- }
- }
-
- /**
- * The writer thread body.
- */
- public void run()
- {
- ArrayList work = null;
- Latch workLatch = null;
-
- while (running)
- {
- synchronized (batchLock)
- {
- if (currentQueue.size() > 0)
- {
- if (work == null)
- work = new ArrayList(initialCapacity);
-
- // Switch currentQueue and work. All write requests that
- // were in currentQueue will be handled as a batch of work.
-
- ArrayList tmp = work;
- work = currentQueue;
- currentQueue = tmp;
- workLatch = currentLatch;
- currentLatch = new Latch();
- }
- else
- {
- // Wait for a write request.
- try
- {
- batchLock.wait();
- }
- catch (InterruptedException ignored)
- {
- if (!running) break;
- Thread.interrupted(); // clear interrupted
- }
- continue;
- }
- }
-
- try
- {
- // Perform the batch of work.
- doWork(work);
- }
- catch (Exception e)
- {
- break;
- }
- finally
- {
- // Let
- workLatch.release();
- work.clear();
- }
- }
- cleanup();
- }
-
- /**
- * Performs a batch of write requests.
- *
- * @param work an <code>ArrayList</code> of
- * <code>PendingWriteRequest</code>s.
- */
- private void doWork(ArrayList work)
- {
- if (abort != null)
- {
- for (int i = 0; i < work.size(); i++)
- {
- PendingWriteRequest request = (PendingWriteRequest) work.get(i);
- request.setFailure(abort);
- }
- return;
- }
-
- ByteBuffer[] records = new ByteBuffer[work.size()];
- int offset = 0;
- try
- {
- int length = records.length;
- int usedSize = log.getPosition();
- int numTransactions;
- boolean done = false;
-
- while (!done)
- {
- int j;
- numTransactions = 0;
-
- for (int i = j = offset; i < length; i++)
- {
- PendingWriteRequest request = (PendingWriteRequest) work.get(i);
- int type = request.getType();
- records[j] = request.getBuffer();
- if (type != PendingWriteRequest.TYPE_END)
- {
- usedSize += records[j].remaining();
- if (type == PendingWriteRequest.TYPE_TX_MULTI_TM)
- usedSize += LogRecord.TX_END_LEN;
-
- if (usedSize > fileSize)
- {
- // will leave the for loop with work to do after restart
- length = i;
- }
- else
- {
- numTransactions++;
- j++;
- }
- }
- else
- {
- // TX_END record: which log should we use?
- BatchLog requestedLog = request.getLogger();
-
- if (requestedLog != log)
- {
- // Use requestedLog instead of the current log
- requestedLog.write(records[j], true);
- // (Do not increment j in this case!)
- }
- else
- {
- // Let the record go to the current log
- j++;
- }
- }
-
- }
- done = (length == records.length);
- length = length - offset;
- log.write(records, offset, j - offset, numTransactions);
- setCompletionHandler(offset, length, work);
- if (!done)
- {
- restart();
- offset = offset + length;
- length = records.length;
- usedSize = log.getPosition();
- }
- }
- }
- catch (IOException failure)
- {
- for (int i = offset; i < records.length - offset; i++)
- {
- PendingWriteRequest request = (PendingWriteRequest) work.get(i);
- request.setFailure(failure);
- }
- if (abort == null)
- restart();
- }
- }
-
- /**
- * Sets to the current <code>BatchLog</code> the completion handler of a
- * range of requests in an <code>ArrayList</code> of
- * <code>PendingWriteRequest</code>s.
- *
- * @param offset index of the first request in the range
- * @param length number of requests in the range
- * @param work an <code>ArrayList</code> of
- * <code>PendingWriteRequest</code>s
- */
- private void setCompletionHandler(int offset, int length, ArrayList work)
- {
- for (int i = offset; i < length; i++)
- {
- PendingWriteRequest request = (PendingWriteRequest) work.get(i);
- if (request.getType() != PendingWriteRequest.TYPE_END)
- request.setCompletionHandler(log);
- }
- }
-
- /**
- * Closes all <code>BatchLog</code>s owned by this <code>BatchWriter</code>.
- */
- private void cleanup()
- {
- synchronized (nextLogs)
- {
-
- for (int i = 0; i < nextLogs.size(); i++)
- {
- BatchLog nextLog = (BatchLog) nextLogs.get(i);
- nextLog.close();
- }
- }
- log.close();
- }
-
- /**
- * Switch the current <code>BatchLog</code>.
- */
- private void restart()
- {
- log.markForRestart();
-
- if (nextLogs.size() > 0)
- log = (BatchLog) nextLogs.remove(0);
- else
- {
- try
- {
- log = new BatchLog(this, header, dir, fileSize);
- }
- catch (IOException e)
- {
- abort = new Exception("FAILED TO RESTART RECOVERY LOG " +
- "AFTER BEING FULL", e);
- }
- }
- }
-
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/recovery/CorruptedLogRecordException.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/recovery/CorruptedLogRecordException.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/recovery/CorruptedLogRecordException.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,43 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.recovery;
-
-/**
- *
- * A CorruptedLogRecordException.
- *
- * @author <a href="reverbel at ime.usp.br">Francisco Reverbel</a>
- * @version $Revision$
- */
-public class CorruptedLogRecordException
- extends RuntimeException
-{
- /** The serialVersionUID */
- private static final long serialVersionUID = -1711360962508810879L;
-
- boolean disablePresumedRollback = false;
-
- CorruptedLogRecordException(String message)
- {
- super(message);
- }
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/recovery/HeuristicStatus.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/recovery/HeuristicStatus.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/recovery/HeuristicStatus.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,61 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.recovery;
-
-/**
- * "Struct class" that groups together the status code for a heuristic
- * decision and a stringfied reference to the remote <code>Resource</code>
- * instance that reported the heuristic decision.
- *
- * @author <a href="mailto:reverbel at ime.usp.br">Francisco Reverbel</a>
- * @version $Revision$
- */
-public class HeuristicStatus
-{
- /**
- * The status code for a heuristic decision. This field uses the same
- * encoding as the <code>errorCode</code> field of a
- * <code>javax.transaction.xa.XAException</code> instance.
- */
- public int code;
-
- /**
- * A stringfied reference to the <code>Resource</code> that reported
- * the heuristic decision.
- */
- public String resourceRef;
-
- /**
- * Constructs a <code>HeuristicStatus</code>.
- *
- * @param code the status code for a heuristic decision, encoded in the
- * same way as the <code>errorCode</code> field of a
- * <code>javax.transaction.xa.XAException</code> instance
- * @param resourceRef a stringfied reference to the <code>Resource</code>
- * that reported the heuristic decision.
- */
- public HeuristicStatus(int code, String resourceRef)
- {
- this.code = code;
- this.resourceRef = resourceRef;
- }
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/recovery/HeuristicStatusLog.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/recovery/HeuristicStatusLog.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/recovery/HeuristicStatusLog.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,133 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.recovery;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import java.nio.ByteBuffer;
-import java.nio.channels.FileChannel;
-
-import org.jboss.logging.Logger;
-
-/**
- * Simple class that appends <code>ByteBuffer</code>s (each of which contains
- * a heuristic status log record) to a log file. Information on heuristically
- * completed transactions does not go to the recovery logs -- it goes to a
- * separate log file. Since heuristic decisions are very rare, there is no need
- * to batch heuristic log writes together.
- *
- * TODO: In this implementation the heuristic status log file grows whenever
- * a record is written to it. This is bad for robustness and should be replaced
- * by an implementation in which the log file has constant lenght (such as the
- * recovery log implementation).
- *
- * @author <a href="mailto:reverbel at ime.usp.br">Francisco Reverbel</a>
- * @version $Revision$
- */
-public class HeuristicStatusLog
-{
- /**
- * Class <code>Logger</code>, for trace messages.
- */
- private static Logger errorLog =
- Logger.getLogger(HeuristicStatusLog.class);
-
- /**
- * True if trace messages should be logged.
- */
- private static boolean traceEnabled = errorLog.isTraceEnabled();
-
- /**
- * The log file.
- */
- private File logFile;
-
- /**
- * A <code>RandomAccessFile</code> view of the log file.
- */
- RandomAccessFile os;
-
- /**
- * The <code>RandomAccessFile</code>'s underlying <code>FileChannel</code>.
- */
- private FileChannel channel;
-
- /**
- * Constructs a new <code>HeuristicStatusLog</code>.
- *
- * @param dir the directory in which the log file will be created.
- * @throws IOException
- */
- HeuristicStatusLog(File dir)
- throws IOException
- {
- logFile = File.createTempFile("HEURISTIC_STATUS_LOG", ".log", dir);
- os = new RandomAccessFile(logFile, "rw");
- channel = os.getChannel();
- channel.force(true);
- }
-
- /**
- * Writes one record at the current position of this
- * <code>HeuristicStatusLog</code>.
- *
- * @param record a buffer with the record to be written
- */
- void write(ByteBuffer record)
- {
- if (traceEnabled)
- {
- errorLog.trace("Heuristic status log record:" +
- HexDump.fromBuffer(record.array()));
- errorLog.trace(LogRecord.toString(record));
- }
-
- try
- {
- channel.write(record);
- channel.force(true);
- }
- catch (IOException e)
- {
- errorLog.error("Error writing heuristic status log " +
- logFile.getName(), e);
- }
- }
-
- /**
- * Closes this <code>HeuristicStatusLog</code>.
- */
- void close()
- {
- try
- {
- os.close();
- }
- catch (IOException e)
- {
- errorLog.error("Error closing heuristic status log " +
- logFile.getName(), e);
- }
- }
-
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/recovery/HeuristicStatusLogReader.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/recovery/HeuristicStatusLogReader.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/recovery/HeuristicStatusLogReader.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,60 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.recovery;
-
-import java.util.Map;
-
-/**
- * Interface that gives access to the information in a heuristic status
- * log file.
- *
- * @author <a href="mailto:reverbel at ime.usp.br">Francisco Reverbel</a>
- * @version $Revision$
- */
-public interface HeuristicStatusLogReader
-{
- /**
- * Gets the name of the underlying heuristic status log file.
- *
- * @return the name of the heuristic status log file.
- */
- String getLogFileName();
-
- /**
- * Recovers information on heuristically completed transactions from
- * the heuristic status log file.
- *
- * @param heuristicallyCompletedTransactions a <code>Map</code> to which
- * this method will one entry per heuristically completed
- * transaction. The map keys are <code>Long</code> values
- * containing local transaction ids. The map values are
- * <code>LogRecord.HeurData</code> objects with information
- * on heuristically completed transactions.
- */
- void recover(Map heuristicallyCompletedTransactions);
-
- /**
- * Removes the underlying heuristic status log file.
- */
- void finishRecovery();
-
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/recovery/HexDump.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/recovery/HexDump.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/recovery/HexDump.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,133 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.recovery;
-
-import java.io.*;
-
-/**
- * Utility class for converting a byte array into a hex dump string.
- *
- * @author <a href="mailto:reverbel at ime.usp.br">Francisco Reverbel</a>
- * @version $Revision$
- */
-public class HexDump
-{
- /**
- * Converts a byte array into an hex dump string.
- *
- * @param buffer the byte array to be converted
- * @return a string containing the hex dump of the <code>buffer</code>.
- */
- public static String fromBuffer(byte[] buffer)
- {
- int n;
- final int N = 16;
- StringBuffer sb = new StringBuffer("\n");
-
- for (int i = 0; (n = Math.min(N, buffer.length - i)) != 0; i = i + n)
- {
- sb.append(toHexString(i) + ": ");
- for (int j = 0; j < n ; j++)
- sb.append(toHexString(buffer[i + j]) + " ");
- for (int j = n; j < N; j++)
- sb.append(" ");
- sb.append(" ");
- for (int j = 0; j < n ; j++)
- sb.append(toDisplayableChar(buffer[i + j]));
- sb.append("\n");
- }
- return sb.toString();
- }
-
- /**
- * Converts a given byte into a string of two hex digits.
- * @param b the byte to be converted
- * @return the string representation of <code>b</code>,
- * as a pair of hex digits.
- */
- private static String toHexString(byte b)
- {
- int i = b; // the byte 0x80 is sign extended to 0xffffff80
- if (i < 0)
- i = i - (int) 0xffffff00; // undo sign extension
- String hexStr = Integer.toHexString(i);
- return (hexStr.length() < 2) ? "0" + hexStr : hexStr;
- }
-
- /**
- * Converts a given integer into a string of up to 8 hex digits left-padded
- * with spaces.
- *
- * @param n the <code>int</code> to be converted
- * @return a string containing the hex digits of <code>n</code> left-padded
- * with spaces so that the total length of the string is 8.
- */
- private static String toHexString(int n)
- {
- String hexStr = Integer.toHexString(n);
- while (hexStr.length() < 8)
- hexStr = " " + hexStr;
- return hexStr;
- }
-
- /**
- * Converts a given byte into a displayable character.
- * @param b the byte to convert
- * @return a char whose value is <code>b</code> (if <code>b</code> is in the
- * displayable range), or the char '.' (otherwise).
- */
- private static char toDisplayableChar(byte b)
- {
- char c = (char) b;
- if (c >= 0x20 && c < 0x7f)
- return c;
- else
- return '.';
- }
-
- /**
- * For testing.
- */
- public static void main(String[] args) throws IOException
- {
- InputStream in;
- byte[] ibuf = new byte[4096];
-
- if (args.length > 1)
- {
- System.err.println("HexDump usage: java HexDump [file]");
- System.exit(1);
- }
- in = (args.length == 0) ? System.in : new FileInputStream(args[0]);
- int n = in.read(ibuf);
- while (n > 0)
- {
- byte[] buf = new byte[n];
- System.arraycopy(ibuf, 0, buf, 0, n);
- System.out.print(fromBuffer(buf));
- n = in.read(ibuf);
- }
- if (args.length != 0)
- in.close();
- }
-
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/recovery/LogRecord.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/recovery/LogRecord.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/recovery/LogRecord.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,1389 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.recovery;
-
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-import java.util.zip.Adler32;
-import java.util.zip.Checksum;
-
-import javax.transaction.xa.Xid;
-
-import org.jboss.tm.TxUtils;
-
-/**
- * Utility class with static methods to create transaction log records and to
- * extract information from transaction log records. It has static methods to
- * create the following kinds of log records:
- * <ul>
- * <li><code>TX_COMMITTED</code> records, which are used for locally-started
- * transactions that do not involve other transaction managers;</li>
- * <li><code>MULTI_TM_TX_COMMITTED</code> records, which are used for
- * locally-started transactions that involve other transaction
- * managers;</li>
- * <li><code>TX_PREPARED</code> records, which are used for foreign
- * transactions that entered this virtual machine in transaction contexts
- * propagated along with remote method invocations;</li>
- * <li><code>JCA_TX_PREPARED</code> records, which are used for foreign
- * transactions that entered this virtual machine through JCA transaction
- * inflow;</li>
- * <li><code>TX_END</code> records, which are used for distributed
- * transactions and mark the end of the second phase of the 2PC subtree
- * coordinated by this transaction manager. They are paired with
- * <code>MULTI_TM_TX_COMMITTED</code>, <code>TX_PREPARED</code>, and
- * <code>JCA_TX_PREPARED</code> records. No <code>TX_END</code> record
- * is written out in the case of a locally-started transaction that
- * involves no external transaction managers. In other words,
- * <code>TX_END</code> records are not paired with
- * <code>TX_COMMITTED</code> records;</li>
- *<li><code>HEUR_STATUS</code> records, which are used to log the
- * heuristic status of a distributed transaction;</li>
- *<li><code>HEUR_FORGOTTEN</code> records, which are used to clear the
- * heuristic status of a distributed transaction.</li>
- * </ul>
- * Layout of <code>MULTI_TM_TX_COMMITTED</code> records:
- * <pre>
- * - magicHeader (an array of HEADER_LEN bytes)
- * - recordLength (short)
- * - recordLengthCheck (short)
- * - recordType (byte)
- * - localTransactionId (long)
- * - countOfDirEntries (N, a short)
- * - varField 0 \
- * ... | <------------ variable-sized fields
- * - varField N-1 /
- * - offset of varField N-1 \ directory of varFields: N dir entries
- * - length of varField N-1 | (each entry contains the length of
- * ... | <-- a varField and the offset of its
- * - offset of varField 0 | first byte relative to the start
- * - length of varField 0 / of the record)
- * - checksum (int)
- * </pre>
- * The varFields of a <code>MULTI_TM_TX_COMMITTED</code> record contain
- * stringfied references for the remote <code>Resource</code>s enlisted in the
- * transaction. Note that the dir entries are stored backwards at the end of
- * the record, that is, the one that appears last (just before the checksum)
- * refers to the first varField, and the one that appears first refers to the
- * last varField.
- * <p>
- * Layout of <code>TX_PREPARED</code> and <code>JCA_TX_PREPARED</code>
- * records:
- * <pre>
- * - magicHeader (an array of HEADER_LEN bytes)
- * - recordLength (short)
- * - recordLengthCheck (short)
- * - recordType (byte)
- * - localTransactionId (long)
- * - countOfDirEntries (N, a short)
- * - inboundFormatId (int)
- * - gidLength (short)
- * - globalTransactionId (an array of gidLength bytes)
- * - varField 0 \
- * ... | <------------ variable-sized fields
- * - varField N-1 /
- * - offset of varField N-1 \ directory of varFields: N dir entries
- * - length of varField N-1 | (each entry contains the length of
- * ... | <-- a varField and the offset of its
- * - offset of varField 0 | first byte relative to the start
- * - length of varField 0 / of the record)
- * - checksum (int)
- * </pre>
- * The inboundFormatId is the formatId of the foreign <code>Xid</code>.
- * In a <code>TX_PREPARED</code> record, the first varField (the one referred
- * to by the dir entry that immediately precedes the checksum) contains a
- * stringfied reference for the <code>RecoveryCoordinator</code> of the
- * transaction.
- * In a <code>JCA_TX_PREPARED</code> record, the first varField contains the
- * inbound branch qualifier, which is the branch qualifier part of the foreign
- * <code>Xid</code> passed to <code>XATerminator.prepare()</code>.
- * The remaining varFields of a <code>TX_PREPARED</code> or
- * <code>JCA_TX_PREPARED</code> records contain stringfied references for the
- * remote <code>Resource</code>s enlisted in the transaction.
- * </p>
- * Layout of <code>TX_COMMITTED</code> records:
- * <pre>
- * - magicHeader (an array of HEADER_LEN bytes)
- * - recordLength (short)
- * - recordLengthCheck (short)
- * - recordType (byte)
- * - localTransactionId (long),
- * - checksum (int)
- * </pre>
- * <p>
- * Layout of <code>TX_END</code> records:
- * <pre>
- * - magicHeader (an array of HEADER_LEN bytes)
- * - recordLength (short)
- * - recordLengthCheck (short)
- * - recordType (byte)
- * - localTransactionId (long),
- * - checksum (int)
- * </pre>
- * <p>
- * Layout of <code>HEUR_STATUS</code> records:
- * <pre>
- * - magicHeader (an array of HEADER_LEN bytes)
- * - recordLength (short)
- * - recordLengthCheck (short)
- * - recordType (byte)
- * - localTransactionId (long)
- * - countOfDirEntries (N, a short)
- * - transactionStatus (byte)
- * - heuristicStatusCode (byte)
- * - locallyDetectedHeuristicHazardFlag (byte)
- * - isForeignTx (byte)
- * - formatId (int)
- * - gidLength (short)
- * - globalTransactionId (an array of gidLength bytes)
- * - varField 0 \
- * ... | <------------ variable-sized fields
- * - varField N-1 /
- * - offset of varField N-1 \ directory of varFields: N dir entries
- * - length of varField N-1 | (each entry contains the length of
- * ... | <-- a varField and the offset of its
- * - offset of varField 0 | first byte relative to the start
- * - length of varField 0 / of the record)
- * - checksum (int)
- * </pre>
- *
- * In a <code>HEUR_STATUS</code> record, the first varField (the one referred
- * to by the dir entry that immediately precedes the checksum) contains the
- * the inbound branch qualifier of a transaction that entered the server via
- * JCA inflow. This varField is empty (i.e., it has zero length) in the case of
- * a transaction that did not enter the server via JCA inflow. The second
- * varField contains a byte array with the heuristic status codes of the XA
- * resources that reported heuristic decisions. This varField is empty if no
- * XA resource reported heuristic decisions. The remaining varFields are
- * associated with remote resources that reported heuristic decisions. Each
- * such varField contains a byte with the heuristic status code reported by the
- * remote resource, followed by a stringfied reference for the remote
- * <code>Resource</code> instance that reported a heuristic decision.
- * <p>
- * Layout of <code>HEUR_FORGOTTEN</code> records:
- * <pre>
- * - magicHeader (an array of HEADER_LEN bytes)
- * - recordLength (short)
- * - recordLengthCheck (short)
- * - recordType (byte)
- * - localTransactionId (long),
- * - checksum (int)
- * </pre>
- * <p>
- * Note that <code>TX_COMMITTED</code>, <code>TX_END</code>, and
- * <code>HEUR_FORGOTTEN</code> records have fixed size. The other types of
- * records are variable-sized.
- * <p>
- * In all record types:
- * <ul>
- * <li>The recordLength is the number of bytes of the part of the record that
- * follows the recordLengthCheck field. It counts the bytes from the
- * recordType field up to (and including) the checksum field.</li>
- * <li>The recordLengthCheck is the arithmetic negation of the recordLength
- * value (i.e,, -recordLength).</li>
- * <li>The checksum is the Adler-32 checksum of the part of the record that
- * starts at the recordType field(which is included in the checksum) and
- * ends at the checksum field (which is not included).</li>
- * </ul>
- * @author <a href="mailto:reverbel at ime.usp.br">Francisco Reverbel</a>
- * @version $Revision$
- */
-public class LogRecord
-{
- /** Magic header placed in all log records.*/
- public static final byte[] HEADER = "Log".getBytes();
-
- /** Length of the magic header. */
- public static final int HEADER_LEN = HEADER.length;
-
- /** Null header that will be read when there are no more log records */
- private static final byte[] NULL_HEADER = {0, 0, 0};
-
- /** Size of a byte, in bytes. */
- private static final int SIZEOF_BYTE = 1;
-
- /** Size of a short, in bytes. */
- static final int SIZEOF_SHORT = 2;
-
- /** Size of a long, in bytes. */
- private static final int SIZEOF_LONG = 8;
-
- /** Length of the inbound format id. */
- private static final int FORMAT_ID_LEN = 4;
-
- /** Length of the checksum. */
- private static final int CHKSUM_LEN = 4;
-
- /** Total length of the magic header plus record length fields. */
- static final int FULL_HEADER_LEN = HEADER_LEN + 2 * SIZEOF_SHORT;
-
- /** Value of recordType field in a single-TM tx committed record */
- static final byte TX_COMMITTED = (byte) 'C';
-
- /** Value of recordType field in a multi-TM tx committed record */
- static final byte MULTI_TM_TX_COMMITTED = (byte) 'M';
-
- /** Value of recordType field in a tx prepared record */
- static final byte TX_PREPARED = (byte) 'P';
-
- /** Value of recordType field in a JCA tx prepared record */
- static final byte JCA_TX_PREPARED = (byte) 'R';
-
- /** Value of recordType field in a tx end record */
- static final byte TX_END = (byte) 'E';
-
- /** Value of recordType field in a heuristic status record */
- static final byte HEUR_STATUS = (byte) 'H';
-
- /** Value of recordType field in a heuristic status record */
- static final byte HEUR_FORGOTTEN = (byte) 'F';
-
- /** Size of varField directory entry */
- private static final int SIZEOF_DIR_ENTRY =
- SIZEOF_SHORT /* offset */
- + SIZEOF_SHORT; /* length */
-
- /**
- * Minimum length of a multi-TM tx committed
- * (<code>MULTI_TM_TX_COMMITTED</code>) record.
- */
- private static final int MIN_MULTI_TM_TX_COMMITTED_LEN =
- HEADER_LEN /* magic header */
- + SIZEOF_SHORT /* record length */
- + SIZEOF_SHORT /* record length check */
- + SIZEOF_BYTE /* record type */
- + SIZEOF_LONG /* local transaction id */
- + SIZEOF_SHORT /* count of dir entries */
- + CHKSUM_LEN; /* checksum */
-
- /**
- * Minimum length of a tx prepared (<code>TX_PREPARED</code>)
- * or JCA tx prepared (<code>JCA_TX_PREPARED</code>) record.
- */
- private static final int MIN_TX_PREPARED_LEN =
- HEADER_LEN /* magic header */
- + SIZEOF_SHORT /* record length */
- + SIZEOF_SHORT /* record length check */
- + SIZEOF_BYTE /* record type */
- + SIZEOF_LONG /* local transaction id */
- + SIZEOF_SHORT /* count of dir entries */
- + FORMAT_ID_LEN /* inbound format id */
- + SIZEOF_SHORT /* length of global transaction id */
- + CHKSUM_LEN; /* checksum */
-
- /**
- * Fixed length of a single-TM tx committed (<code>TX_COMMITTED</code>)
- * record.
- */
- private static final int TX_COMMITED_LEN =
- HEADER_LEN /* magic header */
- + SIZEOF_SHORT /* record length */
- + SIZEOF_SHORT /* record length check */
- + SIZEOF_BYTE /* record type (TX_COMMITTED) */
- + SIZEOF_LONG /* local transaction id */
- + CHKSUM_LEN; /* checksum */
-
- /**
- * Fixed length of a tx end (<code>TX_END</code>) record.
- */
- static final int TX_END_LEN =
- HEADER_LEN /* magic header */
- + SIZEOF_SHORT /* record length */
- + SIZEOF_SHORT /* record length check */
- + SIZEOF_BYTE /* record type (TX_END) */
- + SIZEOF_LONG /* local transaction id */
- + CHKSUM_LEN; /* checksum */
-
- /**
- * Minimum length of a heuristic status (<code>HEUR_STATUS</code>) record.
- */
- private static final int MIN_HEUR_STATUS_LEN =
- HEADER_LEN /* magic header */
- + SIZEOF_SHORT /* record length */
- + SIZEOF_SHORT /* record length check */
- + SIZEOF_BYTE /* record type (HEUR_STATUS) */
- + SIZEOF_LONG /* local transaction id */
- + SIZEOF_SHORT /* count of dir entries */
- + SIZEOF_BYTE /* transaction status */
- + SIZEOF_BYTE /* heuristic status code */
- + SIZEOF_BYTE /* locally-detected heuristic hazard flag */
- + SIZEOF_BYTE /* foreign tx flag */
- + FORMAT_ID_LEN /* format id */
- + SIZEOF_SHORT /* length of global transaction id */
- + SIZEOF_DIR_ENTRY /* varField with inbound branch qualifier */
- + SIZEOF_DIR_ENTRY /* varField with heuristic codes for XA resources */
- + CHKSUM_LEN; /* checksum */
-
- /**
- * Fixed length of a heuristic forgotten (HEUR_FORGOTTEN) record.
- */
- static final int HEUR_FORGOTTEN_LEN =
- HEADER_LEN /* magic header */
- + SIZEOF_SHORT /* record length */
- + SIZEOF_SHORT /* record length check */
- + SIZEOF_BYTE /* record type (HEUR_FORGOTTEN) */
- + SIZEOF_LONG /* local transaction id */
- + CHKSUM_LEN; /* checksum */
-
-
-
- /**
- * Structure filled out by the method <code>LogRecord.getData()</code>.
- */
- public static class Data
- {
- public byte recordType;
- public long localTransactionId;
- public byte[] globalTransactionId;
- public int inboundFormatId;
- public String recoveryCoordinator;
- public byte[] inboundBranchQualifier;
- public String[] resources;
- }
-
- /**
- * Structure filled out by the method <code>LogRecord.getHeurData()</code>.
- */
- public static class HeurData
- {
- public byte recordType;
- public long localTransactionId;
- public boolean foreignTx;
- public int formatId;
- public byte[] globalTransactionId;
- public byte[] inboundBranchQualifier;
- public int transactionStatus;
- public int heuristicStatusCode;
- public boolean locallyDetectedHeuristicHazard;
- public int[] xaResourceHeuristics;
- public HeuristicStatus[] remoteResourceHeuristics;
- }
-
- /**
- * Private constructor to enforce non-instantiability.
- */
- private LogRecord()
- {
- }
-
- /**
- * Creates a tx committed record for a locally-started transaction that
- * does not involve other transaction managers.
- *
- * @param localTransactionId the local id of the transaction
- * @return a <code>ByteBuffer</code> containing the tx committed record.
- * The buffer position is set to zero and the buffer limit is set
- * to the number of bytes in the commit record.
- */
- static ByteBuffer createTxCommittedRecord(long localTransactionId)
- {
- ByteBuffer buffer = ByteBuffer.allocate(TX_COMMITED_LEN);
-
- buffer.put(HEADER)
- .putShort((short) (TX_COMMITED_LEN - FULL_HEADER_LEN))
- .putShort((short) -(TX_COMMITED_LEN - FULL_HEADER_LEN))
- .put(TX_COMMITTED)
- .putLong(localTransactionId);
-
- Checksum checksum = new Adler32();
- checksum.update(buffer.array(),
- FULL_HEADER_LEN,
- SIZEOF_BYTE + SIZEOF_LONG);
- buffer.putInt(TX_COMMITED_LEN - CHKSUM_LEN, (int) checksum.getValue());
-
- return (ByteBuffer) buffer.position(0);
- }
-
- /**
- * Creates a multi-TM tx committed record for a distributed transaction.
- *
- * @param localTransactionId the local id of the transaction
- * @param resources an array of stringfied references for the remote
- * resources (<code>org.jboss.tm.remoting.Resource</code>
- * instances) enlisted in the transaction.
- * @return a <code>ByteBuffer</code> containing the tx committed record.
- * The buffer position is set to zero and the buffer limit is set
- * to the number of bytes in the record.
- */
- static ByteBuffer createTxCommittedRecord(long localTransactionId,
- String[] resources)
- {
- int recordLen = MIN_MULTI_TM_TX_COMMITTED_LEN;
- int resourceCount = 0;
-
- if (resources != null && (resourceCount = resources.length) > 0)
- {
- for (int i = 0; i < resourceCount; i++)
- {
- recordLen += SIZEOF_DIR_ENTRY /* offset and length */
- + resources[i].length(); /* data */
- }
- }
- else
- throw new RuntimeException("No remote resources were specified");
-
- ByteBuffer buffer = ByteBuffer.allocate(recordLen);
-
- buffer.put(HEADER)
- .putShort((short) (recordLen - FULL_HEADER_LEN))
- .putShort((short) -(recordLen - FULL_HEADER_LEN))
- .put(MULTI_TM_TX_COMMITTED)
- .putLong(localTransactionId)
- .putShort((short) resourceCount);
-
- for (int i= 0; i < resourceCount; i++)
- {
- int offset = buffer.position();
- int length = resources[i].length();
- byte[] resourceBytes = new byte[length];
-
- resources[i].getBytes(0, length, resourceBytes, 0);
- buffer.put(resourceBytes)
- .putShort(recordLen
- - CHKSUM_LEN - SIZEOF_SHORT - SIZEOF_DIR_ENTRY * i,
- (short) length)
- .putShort(recordLen
- - CHKSUM_LEN - SIZEOF_DIR_ENTRY - SIZEOF_DIR_ENTRY * i,
- (short) offset);
- }
-
- Checksum checksum = new Adler32();
- checksum.update(buffer.array(),
- FULL_HEADER_LEN,
- recordLen - FULL_HEADER_LEN - CHKSUM_LEN);
- buffer.putInt(recordLen - CHKSUM_LEN, (int) checksum.getValue());
-
- return (ByteBuffer) buffer.position(0);
- }
-
- /**
- * Creates a tx prepared record or a JCA tx prepared record.
- *
- * @param localTransactionId the local id of the transaction
- * @param inboundFormatId the format id of the foreign <code>Xid</code>
- * @param globalTransactionId the global id of the transaction
- * @param jcaInboundTransaction true if this method should create a JCA tx
- * prepared record, false if this method should
- * create a tx prepared record
- * @param recoveryCoordOrInboundBranchQual an stringfied recovery
- * coordinator converted to a byte array (if
- * jcaInboundTransaction is false) or the inbound
- * branch qualifier of a JCA inbound transaction (if
- * jcaInboundTransaction is true)
- * @param resources an array of stringfied references for the remote
- * resources (<code>org.jboss.tm.remoting.Resource</code>
- * instances) enlisted in the transaction.
- * @return a <code>ByteBuffer</code> containing the tx prepared record or
- * JCA tx prepared record. The buffer position is set to zero and
- * the buffer limit is set to the number of bytes in the record.
- */
- private static ByteBuffer createTxPreparedRecord(
- long localTransactionId,
- int inboundFormatId,
- byte[] globalTransactionId,
- boolean jcaInboundTransaction,
- byte[] recoveryCoordOrInboundBranchQual,
- String[] resources)
- {
- int recordLen = MIN_TX_PREPARED_LEN;
- int globalTxIdLen = 0;
- int resourceCount = 0;
-
- if (globalTransactionId != null &&
- (globalTxIdLen = globalTransactionId.length) > 0)
- {
- recordLen += globalTxIdLen;
- }
- else
- throw new RuntimeException("The global transaction id " +
- "was not specified");
-
- if (resources != null && (resourceCount = resources.length) > 0)
- {
- for (int i = 0; i < resourceCount; i++)
- {
- recordLen += SIZEOF_DIR_ENTRY /* dir entry */
- + resources[i].length(); /* data */
- }
- }
-
- recordLen += SIZEOF_DIR_ENTRY /* dir entry */
- + recoveryCoordOrInboundBranchQual.length; /* data */
-
- ByteBuffer buffer = ByteBuffer.allocate(recordLen);
-
- buffer.put(HEADER)
- .putShort((short) (recordLen - FULL_HEADER_LEN))
- .putShort((short) -(recordLen - FULL_HEADER_LEN))
- .put(jcaInboundTransaction ? JCA_TX_PREPARED : TX_PREPARED)
- .putLong(localTransactionId)
- .putShort((short) (resourceCount + 1))
- .putInt(inboundFormatId)
- .putShort((short) globalTxIdLen)
- .put(globalTransactionId);
-
- int offset = buffer.position();
- int length = recoveryCoordOrInboundBranchQual.length;
-
- buffer.put(recoveryCoordOrInboundBranchQual)
- .putShort(recordLen - CHKSUM_LEN - SIZEOF_SHORT, (short) length)
- .putShort(recordLen - CHKSUM_LEN - SIZEOF_DIR_ENTRY,
- (short) offset);
-
- for (int i = 0; i < resourceCount; )
- {
- offset = buffer.position();
- length = resources[i].length();
- byte[] byteArray = new byte[length];
-
- resources[i].getBytes(0, length, byteArray, 0);
- i++; // increment i *before* storing the entry (because entry 0 is
- // the recovery coordinator or inbound branch qualifier)
- buffer.put(byteArray)
- .putShort(recordLen
- - CHKSUM_LEN - SIZEOF_SHORT - SIZEOF_DIR_ENTRY * i,
- (short) length)
- .putShort(recordLen
- - CHKSUM_LEN - SIZEOF_DIR_ENTRY - SIZEOF_DIR_ENTRY * i,
- (short) offset);
- }
-
- Checksum checksum = new Adler32();
- checksum.update(buffer.array(),
- FULL_HEADER_LEN,
- recordLen - FULL_HEADER_LEN - CHKSUM_LEN);
- buffer.putInt(recordLen - CHKSUM_LEN, (int) checksum.getValue());
-
- return (ByteBuffer) buffer.position(0);
- }
-
- /**
- * Creates a tx prepared record for a distributed transaction.
- *
- * @param localTransactionId the local id of the transaction
- * @param inboundFormatId the format id of the foreign <code>Xid</code>
- * @param globalTransactionId the global id of the transaction
- * @param recoveryCoordinator a stringfied reference for the remote
- * coordinator, an
- * <code>org.jboss.tm.remoting.RecoveryCoordinator</code>
- * instance
- * @param resources an array of stringfied references for the remote
- * resources (<code>org.jboss.tm.remoting.Resource</code>
- * instances) enlisted in the transaction.
- * @return a <code>ByteBuffer</code> containing the tx prepared record.
- * The buffer position is set to zero and the buffer limit is set
- * to the number of bytes in the record.
- */
- static ByteBuffer createTxPreparedRecord(long localTransactionId,
- int inboundFormatId,
- byte[] globalTransactionId,
- String recoveryCoordinator,
- String[] resources)
- {
- int len = recoveryCoordinator.length();
- byte[] coordinatorByteArray = new byte[len];
-
- recoveryCoordinator.getBytes(0, len, coordinatorByteArray, 0);
-
- return createTxPreparedRecord(localTransactionId,
- inboundFormatId,
- globalTransactionId,
- false /* not JCA inbound */,
- coordinatorByteArray,
- resources);
- }
-
- /**
- * Creates a tx prepared record for a JCA inbound transaction.
- *
- * @param localTransactionId the local id of the transaction
- * @param inboundXid a foreign <code>Xid</code> instance
- * @param resources an array of stringfied references for the remote
- * resources (<code>org.jboss.tm.remoting.Resource</code>
- * instances) enlisted in the transaction.
- * @return a <code>ByteBuffer</code> containing the JCA tx prepared record.
- * The buffer position is set to zero and the buffer limit is set
- * to the number of bytes in the record.
- */
- static ByteBuffer createJcaTxPreparedRecord(long localTransactionId,
- Xid inboundXid,
- String[] resources)
- {
- return createTxPreparedRecord(localTransactionId,
- inboundXid.getFormatId(),
- inboundXid.getGlobalTransactionId(),
- true /* JCA inbound */,
- inboundXid.getBranchQualifier(),
- resources);
- }
-
- /**
- * Creates a tx end record for a distributed transaction.
- *
- * @param localTransactionId the local id of the transaction.
- * @return a <code>ByteBuffer</code> containing the end record. The
- * buffer position is set to zero and the buffer limit is set to
- * the number of bytes in the end record.
- */
- static ByteBuffer createTxEndRecord(long localTransactionId)
- {
- ByteBuffer buffer = ByteBuffer.allocate(TX_END_LEN);
-
- buffer.put(HEADER)
- .putShort((short) (TX_END_LEN - FULL_HEADER_LEN))
- .putShort((short) -(TX_END_LEN - FULL_HEADER_LEN))
- .put(TX_END)
- .putLong(localTransactionId);
-
- Checksum checksum = new Adler32();
- checksum.update(buffer.array(),
- FULL_HEADER_LEN,
- SIZEOF_BYTE + SIZEOF_LONG);
- buffer.putInt(TX_END_LEN - CHKSUM_LEN, (int) checksum.getValue());
-
- return (ByteBuffer) buffer.position(0);
- }
-
- /**
- * Creates a heuristic status record for a transaction.
- *
- * @param localTransactionId the local id of the transaction
- * @param foreignTx true if the transaction is a foreign one, false otherwise
- * @param formatId the format id field of the transaction's <code>Xid</code>
- * @param globalTransactionId the global id field of the transaction's
- * <code>Xid</code>
- * @param inboundBranchQualifier the inbound branch qualifier, in the case
- * of a foreign transaction that has been imported via JCA
- * transaction inflow, or null otherwise
- * @param transactionStatus the transaction status
- * (<code>javax.transaction.Status.STATUS_COMMITTING</code>, or
- * <code>javax.transaction.Status.STATUS_COMMITTED</code>, or
- * <code>javax.transaction.Status.STATUS_ROLLING_BACK</code>, or
- * <code>javax.transaction.Status.STATUS_ROLLEDBACK</code>)
- * @param heurStatusCode the heuristic status code, which takes the same
- * values as the <code>errorCode</code> field of
- * <code>javax.transaction.xa.XAException</code>
- * @param locallyDetectedHeuristicHazard true if a heuristic hazard was
- * detected locally and is still outstanding
- * @param xaResourceHeuristics array with the heuristic status codes of
- * the XA resources that reported heuristic decisions,
- * or null if no XA resources reported heuristic decisions
- * @param remoteResourceHeuristics array with the heuristic status of
- * the remote resources that reported heuristic decisions,
- * or null if no remote resources reported heuristic
- * decisions
- * @return a <code>ByteBuffer</code> containing the heuristic status record.
- * The buffer position is set to zero and the buffer limit is set
- * to the number of bytes in the record.
- */
- static ByteBuffer createHeurStatusRecord(
- long localTransactionId,
- boolean foreignTx,
- int formatId,
- byte[] globalTransactionId,
- byte[] inboundBranchQualifier,
- int transactionStatus,
- int heurStatusCode,
- boolean locallyDetectedHeuristicHazard,
- int[] xaResourceHeuristics,
- HeuristicStatus[] remoteResourceHeuristics)
- {
- int recordLen = MIN_HEUR_STATUS_LEN;
- int globalTxIdLen = 0;
- int remoteResourceHeuristicsCount = 0;
-
- if (globalTransactionId != null)
- recordLen += (globalTxIdLen = globalTransactionId.length);
- if (inboundBranchQualifier != null)
- recordLen += inboundBranchQualifier.length;
- if (xaResourceHeuristics != null)
- recordLen += xaResourceHeuristics.length;
- if (remoteResourceHeuristics != null)
- {
- remoteResourceHeuristicsCount = remoteResourceHeuristics.length;
- for (int i = 0; i < remoteResourceHeuristicsCount; i++)
- {
- recordLen += SIZEOF_DIR_ENTRY /* offset and length */
- + SIZEOF_BYTE /* data */
- + remoteResourceHeuristics[i].resourceRef.length();
- }
- }
-
- ByteBuffer buffer = ByteBuffer.allocate(recordLen);
-
- buffer.put(HEADER)
- .putShort((short) (recordLen - FULL_HEADER_LEN))
- .putShort((short) -(recordLen - FULL_HEADER_LEN))
- .put(HEUR_STATUS)
- .putLong(localTransactionId)
- .putShort((short) (remoteResourceHeuristicsCount + 2))
- .put((byte) transactionStatus)
- .put((byte) heurStatusCode)
- .put((locallyDetectedHeuristicHazard) ? (byte) 1 : (byte) 0)
- .put((foreignTx) ? (byte) 1 : (byte) 0)
- .putInt(formatId)
- .putShort((short) globalTxIdLen)
- .put(globalTransactionId);
-
-
- int offset, length;
-
- // varField 0: inboundBranchQualifier
- offset = buffer.position();
- length = (inboundBranchQualifier == null) ? 0
- : inboundBranchQualifier.length;
- if (length > 0)
- buffer.put(inboundBranchQualifier);
- buffer.putShort(recordLen - CHKSUM_LEN - SIZEOF_SHORT, (short) length)
- .putShort(recordLen - CHKSUM_LEN - SIZEOF_DIR_ENTRY, (short) offset);
-
- // varField 1: xaResourceHeuristics
- offset = buffer.position();
- length = (xaResourceHeuristics == null) ? 0
- : xaResourceHeuristics.length;
- if (length > 0)
- {
- byte[] xaResHeurCodes = new byte[length];
- for (int i = 0; i < length; i++)
- xaResHeurCodes[i] = (byte) xaResourceHeuristics[i];
- buffer.put(xaResHeurCodes);
- }
- buffer.putShort(recordLen - CHKSUM_LEN
- - SIZEOF_SHORT - SIZEOF_DIR_ENTRY,
- (short) length)
- .putShort(recordLen - CHKSUM_LEN
- - SIZEOF_DIR_ENTRY - SIZEOF_DIR_ENTRY,
- (short) offset);
-
- // varField 2, ... : remoteResourceHeuristics
- for (int i = 0 ; i < remoteResourceHeuristicsCount; i++)
- {
- String resourceRef = remoteResourceHeuristics[i].resourceRef;
- offset = buffer.position();
- length = resourceRef.length() + 1;
- byte[] heurStatus = new byte[length];
- heurStatus[0] = (byte) remoteResourceHeuristics[i].code;
- resourceRef.getBytes(0, resourceRef.length(), heurStatus, 1);
- buffer.put(heurStatus)
- .putShort(recordLen - CHKSUM_LEN
- - SIZEOF_SHORT - SIZEOF_DIR_ENTRY * (i + 2),
- (short) length)
- .putShort(recordLen - CHKSUM_LEN
- - SIZEOF_DIR_ENTRY - SIZEOF_DIR_ENTRY * (i + 2),
- (short) offset);
- }
-
- Checksum checksum = new Adler32();
- checksum.update(buffer.array(),
- FULL_HEADER_LEN,
- recordLen - FULL_HEADER_LEN - CHKSUM_LEN);
- buffer.putInt(recordLen - CHKSUM_LEN, (int) checksum.getValue());
-
- return (ByteBuffer) buffer.position(0);
- }
-
- /**
- * Creates a heuristic forgotten record for a transaction.
- *
- * @param localTransactionId the local id of the transaction.
- * @return a <code>ByteBuffer</code> containing the heuristic forgotten
- * record. The buffer position is set to zero and the buffer limit
- * is set to the number of bytes in the heuristic forgotten record.
- */
- static ByteBuffer createHeurForgottenRecord(long localTransactionId)
- {
- ByteBuffer buffer = ByteBuffer.allocate(HEUR_FORGOTTEN_LEN);
-
- buffer.put(HEADER)
- .putShort((short) (HEUR_FORGOTTEN_LEN - FULL_HEADER_LEN))
- .putShort((short) -(HEUR_FORGOTTEN_LEN - FULL_HEADER_LEN))
- .put(HEUR_FORGOTTEN)
- .putLong(localTransactionId);
-
- Checksum checksum = new Adler32();
- checksum.update(buffer.array(),
- FULL_HEADER_LEN,
- SIZEOF_BYTE + SIZEOF_LONG);
- buffer.putInt(TX_END_LEN - CHKSUM_LEN, (int) checksum.getValue());
-
- return (ByteBuffer) buffer.position(0);
- }
-
- /**
- * Fills out a <code>Data</code> structure with the information taken from
- * the log record in a given <code>ByteBuffer</code>. The log record starts
- * at the beginning of the buffer. It cannot be a log record with heuristic
- * information (i.e., its type cannot be <code>HEUR_STATUS</code> or
- * <code>HEUR_FORGOTTEN</code>). Its length is known in advance and may
- * be smaller than the number of bytes in the buffer. The magic header and
- * record length fields are not included in the <code>ByteBuffer</code>,
- * whose first byte is the record type of the log record.
- *
- * @param buffer a <code>ByteBuffer</code> containing the part of a log
- * record that starts at the record type field (which is the
- * first byte of the <code>ByteBuffer</code> and goes until
- * the checksum field (which is included in the
- * <code>ByteBuffer</code>
- * @param recLen the length of the log record in the buffer
- * @param data a <code>Data</code> structure to be filled out with the
- * information extracted from the log record.
- */
- static void getData(ByteBuffer buffer, int recLen, Data data)
- {
- short gidLength;
- short countOfDirEntries;
-
- if (recLen > buffer.limit())
- return; // TODO: throw an exception in this case
-
- int checksumField = buffer.getInt(recLen - CHKSUM_LEN);
-
- Checksum checksum = new Adler32();
- checksum.update(buffer.array(), 0, recLen - CHKSUM_LEN);
-
- if ((int) checksum.getValue() != checksumField)
- {
- throw new CorruptedLogRecordException("Wrong checksum.");
- }
-
- data.recordType = buffer.get();
-
- switch (data.recordType)
- {
- case MULTI_TM_TX_COMMITTED:
- data.localTransactionId = buffer.getLong();
- countOfDirEntries = buffer.getShort();
-
- // Get varField 0, ..., varField N (where N = countOfDirEntries - 1)
- data.resources = new String[countOfDirEntries];
- for (int i = 0; i < countOfDirEntries; i++)
- {
- short length = buffer.getShort(recLen - CHKSUM_LEN
- - SIZEOF_SHORT
- - SIZEOF_DIR_ENTRY * i);
- short offset = buffer.getShort(recLen - CHKSUM_LEN
- - SIZEOF_DIR_ENTRY
- - SIZEOF_DIR_ENTRY * i);
- offset -= FULL_HEADER_LEN; // Our buffer starts after the header!
- data.resources[i] = new String(buffer.array(), 0, offset, length);
- }
-
- // Nullify unused data fields
- data.globalTransactionId = null;
- data.inboundFormatId = -1;
- data.recoveryCoordinator = null;
- data.inboundBranchQualifier = null;
- break;
-
- case TX_PREPARED:
- case JCA_TX_PREPARED:
- data.localTransactionId = buffer.getLong();
- countOfDirEntries = buffer.getShort();
- data.inboundFormatId = buffer.getInt();
- gidLength = buffer.getShort();
- data.globalTransactionId = new byte[gidLength];
- buffer.get(data.globalTransactionId);
-
- // Get lentgh and offset of varField 0:
- short length = buffer.getShort(recLen - CHKSUM_LEN - SIZEOF_SHORT);
- short offset = buffer.getShort(recLen - CHKSUM_LEN - SIZEOF_DIR_ENTRY);
- offset -= FULL_HEADER_LEN; // Our buffer starts after the header!
- // (Alternatively we could have set offset to buffer.position(),
- // as varField 0 cames immediately after the globalTransactionId.)
-
- if (data.recordType == TX_PREPARED)
- {
- // varField 0 is the recovery coordinator
- data.recoveryCoordinator =
- new String(buffer.array(), 0, offset, length);
- data.inboundBranchQualifier = null;
- }
- else
- {
- // varField 0 is the inbound branch qualifier
- data.recoveryCoordinator = null;
- data.inboundBranchQualifier = new byte[length];
- // At this point (offset == buffer.position),
- // so the line below is commented out:
- // buffer.position(offset);
- buffer.get(data.inboundBranchQualifier);
- }
-
- // Get varField 1, ... varField N (where N == countOfDirEntries - 1)
- data.resources = new String[countOfDirEntries - 1];
- for (int i = 1; i < countOfDirEntries; i++)
- {
- length = buffer.getShort(recLen - CHKSUM_LEN
- - SIZEOF_SHORT
- - SIZEOF_DIR_ENTRY * i);
- offset = buffer.getShort(recLen - CHKSUM_LEN
- - SIZEOF_DIR_ENTRY
- - SIZEOF_DIR_ENTRY * i);
- offset -= FULL_HEADER_LEN; // Our buffer starts after the header!
- data.resources[i - 1] =
- new String(buffer.array(), 0, offset, length);
- }
- break;
-
- case TX_COMMITTED:
- case TX_END:
- data.localTransactionId = buffer.getLong();
- // Nullify the remaining data fields
- data.globalTransactionId = null;
- data.inboundFormatId = -1;
- data.recoveryCoordinator = null;
- data.inboundBranchQualifier = null;
- data.resources = null;
- break;
-
- case HEUR_STATUS:
- case HEUR_FORGOTTEN:
- throw new RuntimeException("Log record with unexpected type");
-
- default:
- throw new RuntimeException("Log record with invalid type");
- }
- }
-
- /**
- * Fills out a <code>HeurData</code> structure with the information taken
- * from the <code>HEUR_STATUS</code> or <code>HEUR_FORGOTTEN</code> log
- * record in a given <code>ByteBuffer</code>. The log record starts at the
- * beginning of the buffer. Its length is known in advance and may be
- * smaller than the number of bytes in the buffer. The magic header and
- * record length fields are not included in the <code>ByteBuffer</code>,
- * whose first byte is the record type of the log record.
- *
- * @param buffer a <code>ByteBuffer</code> containing the part of a
- * <code>HEUR_STATUS</code> or <code>HEUR_FORGOTTEN</code> log
- * record that starts at the record type field (which is the
- * first byte of the <code>ByteBuffer</code> and goes until
- * the checksum field (which is included in the
- * <code>ByteBuffer</code>
- * @param recLen the length of the log record in the buffer
- * @param data a <code>HeurData</code> structure to be filled out with the
- * information extracted from the log record.
- */
- static void getHeurData(ByteBuffer buffer, int recLen, HeurData data)
- {
- if (recLen > buffer.limit())
- return; // TODO: throw an exception in this case
-
- int checksumField = buffer.getInt(recLen - CHKSUM_LEN);
-
- Checksum checksum = new Adler32();
- checksum.update(buffer.array(), 0, recLen - CHKSUM_LEN);
-
- if ((int) checksum.getValue() != checksumField)
- {
- throw new CorruptedLogRecordException("Wrong checksum.");
- }
-
- data.recordType = buffer.get();
-
- switch (data.recordType)
- {
- case HEUR_STATUS:
- data.localTransactionId = buffer.getLong();
- short countOfDirEntries = buffer.getShort();
- data.transactionStatus = buffer.get();
- data.heuristicStatusCode = buffer.get();
- data.locallyDetectedHeuristicHazard = (buffer.get() != 0);
- data.foreignTx = (buffer.get() != 0);
- data.formatId = buffer.getInt();
- int gidLength = buffer.getShort();
- data.globalTransactionId = new byte[gidLength];
- buffer.get(data.globalTransactionId);
-
- short length, offset;
-
- // Get lentgh and offset of varField 0:
- length = buffer.getShort(recLen - CHKSUM_LEN - SIZEOF_SHORT);
- offset = buffer.getShort(recLen - CHKSUM_LEN - SIZEOF_DIR_ENTRY);
- offset -= FULL_HEADER_LEN; // Our buffer starts after the header!
- // (Alternatively we could have set offset to buffer.position(),
- // as varField 0 cames immediately after the globalTransactionId.)
-
- if (length == 0)
- data.inboundBranchQualifier = null;
- else
- {
- data.inboundBranchQualifier = new byte[length];
- // At this point (offset == buffer.position),
- // so the line below is commented out:
- // buffer.position(offset);
- buffer.get(data.inboundBranchQualifier);
- }
-
- // Get lentgh and offset of varField 1:
- length = buffer.getShort(recLen - CHKSUM_LEN - SIZEOF_SHORT - SIZEOF_DIR_ENTRY);
- offset = buffer.getShort(recLen - CHKSUM_LEN - SIZEOF_DIR_ENTRY - SIZEOF_DIR_ENTRY);
- offset -= FULL_HEADER_LEN; // Our buffer starts after the header!
-
- if (length == 0)
- data.xaResourceHeuristics = null;
- else
- {
- byte[] xaResHeurCodes = new byte[length];
- buffer.position(offset);
- buffer.get(xaResHeurCodes);
- data.xaResourceHeuristics = new int[length];
- for (int i = 0; i < length; i++)
- data.xaResourceHeuristics[i] = xaResHeurCodes[i];
- }
-
- if (countOfDirEntries > 2)
- data.remoteResourceHeuristics =
- new HeuristicStatus[countOfDirEntries - 2];
- else
- data.remoteResourceHeuristics = null;
-
- // Get varField 2, ... varField N (where N == countOfDirEntries - 1)
- for (int i = 2; i < countOfDirEntries; i++)
- {
- length = buffer.getShort(recLen - CHKSUM_LEN
- - SIZEOF_SHORT
- - SIZEOF_DIR_ENTRY * i);
- offset = buffer.getShort(recLen - CHKSUM_LEN
- - SIZEOF_DIR_ENTRY
- - SIZEOF_DIR_ENTRY * i);
- offset -= FULL_HEADER_LEN; // Our buffer starts after the header!
-
- byte remoteResourceHeurCode = buffer.get(offset);
- String remoteResourceRef =
- new String(buffer.array(), 0, offset + 1, length - 1);
- data.remoteResourceHeuristics[i - 2] =
- new HeuristicStatus(remoteResourceHeurCode, remoteResourceRef);
- }
- break;
-
- case HEUR_FORGOTTEN:
- data.localTransactionId = buffer.getLong();
- data.heuristicStatusCode = 0;
- data.xaResourceHeuristics = null;
- data.remoteResourceHeuristics = null;
- break;
-
- case MULTI_TM_TX_COMMITTED:
- case TX_PREPARED:
- case JCA_TX_PREPARED:
- case TX_COMMITTED:
- case TX_END:
- throw new RuntimeException("Log record with unexpected type");
-
- default:
- throw new RuntimeException("Log record with invalid type");
-
- }
- }
-
- /**
- * Gets the lenght of the log record that follows the one at the beginning
- * of a given buffer. This method assumes that the header, record lenght,
- * and record length check of the next record follows the current record
- * in the buffer.
- *
- * @param buffer a <code>ByteBuffer</code> containing the header, record
- * lenght, and record length check of the next log record
- * @param currentRecordLen the buffer position at which the header starts.
- * @return the next record length, a short value read from the absolute
- * buffer position <code>currentRecordLength + HEADER_LEN</code>
- *
- */
- static int getNextRecordLength(ByteBuffer buffer, int currentRecordLength)
- {
- buffer.position(currentRecordLength);
- if (buffer.remaining() < FULL_HEADER_LEN)
- return 0;
- else
- {
- byte[] header = new byte[HEADER_LEN];
- buffer.get(header);
- if (!Arrays.equals(header, HEADER))
- {
- if (Arrays.equals(header, NULL_HEADER))
- return 0;
- else
- throw new CorruptedLogRecordException("Invalid header.");
- }
- else
- {
- short recLen = buffer.getShort();
- short recLenCheck = buffer.getShort();
- if (recLenCheck != -recLen)
- throw new CorruptedLogRecordException("Record lenght check failed.");
- return recLen;
-
- }
- }
- }
-
- /**
- * Receives a byte array containing the part of a log record that follows
- * the header and verifies if the record has a valid checksum.
- *
- * @param buf a byte array containing the part of a log record that starts
- * with the record type and ends with the checksum, which is
- * included in the array.
- * @return true if the checksum is valid, false otherwise.
- */
- static boolean hasValidChecksum(byte[] buf)
- {
- int bufLen = buf.length;
- int checksumField = ByteBuffer.wrap(buf).getInt(bufLen - CHKSUM_LEN);
- Checksum checksum = new Adler32();
- checksum.update(buf, 0, bufLen - CHKSUM_LEN);
- return ((int) checksum.getValue() == checksumField);
- }
-
- /**
- * Returs the string representation of the log record in a buffer.
- *
- * @param buffer a <code>ByteBuffer</code> containing a log record,
- * with the buffer position set to zero and the buffer limit
- * set to the number of bytes in the commit record.
- * @return a string that describes the log record.
- */
- static String toString(ByteBuffer buffer)
- {
- short countOfDirEntries;
- short offset;
- short length;
- short gidLen;
- byte[] gid;
-
- int recLen = buffer.limit();
- buffer.position(FULL_HEADER_LEN);
-
- StringBuffer sb = new StringBuffer("Record Info:\n Type: ");
- byte recordType = buffer.get();
-
- switch (recordType)
- {
- case MULTI_TM_TX_COMMITTED:
- sb.append("MULTI_TM_TX_COMMITTED\n");
- sb.append(" Local transaction id: ");
- sb.append(buffer.getLong());
- sb.append("\n");
- countOfDirEntries = buffer.getShort();
- if (countOfDirEntries > 0)
- {
- sb.append(" Resources:\n");
- // Get varField 0, ..., varField N (where N = countOfDirEntries - 1)
- for (int i = 0; i < countOfDirEntries; i++)
- {
- length = buffer.getShort(recLen - CHKSUM_LEN
- - SIZEOF_SHORT
- - SIZEOF_DIR_ENTRY * i);
- offset = buffer.getShort(recLen - CHKSUM_LEN
- - SIZEOF_DIR_ENTRY
- - SIZEOF_DIR_ENTRY * i);
- sb.append(" ");
- sb.append(new String(buffer.array(), 0, offset, length));
- sb.append("\n");
- }
- }
- break;
- case TX_PREPARED:
- sb.append("TX_PREPARED\n");
- sb.append(" Local transaction id: ");
- sb.append(buffer.getLong());
- sb.append("\n");
- countOfDirEntries = buffer.getShort();
- sb.append(" Inbound format id: ");
- sb.append(buffer.getInt());
- sb.append("\n");
- gidLen = buffer.getShort();
- sb.append(" Global transaction id: ");
- gid = new byte[gidLen];
- buffer.get(gid);
- sb.append(new String(gid, 0));
- sb.append("\n");
- sb.append(" Recovery coordinator: ");
- // Get varField 0
- length = buffer.getShort(recLen - CHKSUM_LEN - SIZEOF_SHORT);
- offset = buffer.getShort(recLen - CHKSUM_LEN - SIZEOF_DIR_ENTRY);
- sb.append(new String(buffer.array(), 0, offset, length));
- sb.append("\n");
- if (countOfDirEntries > 1)
- {
- sb.append(" Resources:\n");
- // Get varField 1, ..., varField N (where N = countOfDirEntries - 1)
- for (int i = 1; i < countOfDirEntries; i++)
- {
- length = buffer.getShort(recLen - CHKSUM_LEN
- - SIZEOF_SHORT
- - SIZEOF_DIR_ENTRY * i);
- offset = buffer.getShort(recLen - CHKSUM_LEN
- - SIZEOF_DIR_ENTRY
- - SIZEOF_DIR_ENTRY * i);
- sb.append(" ");
- sb.append(new String(buffer.array(), 0, offset, length));
- }
- }
- break;
- case JCA_TX_PREPARED:
- sb.append("JCA_TX_PREPARED\n");
- sb.append(" Local transaction id: ");
- sb.append(buffer.getLong());
- sb.append("\n");
- countOfDirEntries = buffer.getShort();
- sb.append(" Inbound format id: ");
- sb.append(buffer.getInt());
- sb.append("\n");
- gidLen = buffer.getShort();
- sb.append(" Global transaction id: ");
- gid = new byte[gidLen];
- buffer.get(gid);
- sb.append(new String(gid, 0));
- sb.append("\n");
- sb.append(" Inbound branch qualifier: ");
- // Get varField 0
- length = buffer.getShort(recLen - CHKSUM_LEN - SIZEOF_SHORT);
- offset = buffer.getShort(recLen - CHKSUM_LEN - SIZEOF_DIR_ENTRY);
- sb.append(new String(buffer.array(), 0, offset, length));
- sb.append("\n");
- if (countOfDirEntries > 1)
- {
- sb.append(" Resources:\n");
- // Get varField 1, ..., varField N (where N = countOfDirEntries - 1)
- for (int i = 1; i < countOfDirEntries; i++)
- {
- length = buffer.getShort(recLen - CHKSUM_LEN
- - SIZEOF_SHORT
- - SIZEOF_DIR_ENTRY * i);
- offset = buffer.getShort(recLen - CHKSUM_LEN
- - SIZEOF_DIR_ENTRY
- - SIZEOF_DIR_ENTRY * i);
- sb.append(" ");
- sb.append(new String(buffer.array(), 0, offset, length));
- }
- }
- break;
- case TX_COMMITTED:
- sb.append("TX_COMMITTED\n");
- sb.append(" Local transaction id: ");
- sb.append(buffer.getLong());
- sb.append("\n");
- break;
- case TX_END:
- sb.append("TX_END\n");
- sb.append(" Local transaction id: ");
- sb.append(buffer.getLong());
- sb.append("\n");
- break;
- case HEUR_STATUS:
- sb.append("HEUR_STATUS\n");
- sb.append(" Local transaction id: ");
- sb.append(buffer.getLong());
- sb.append("\n");
- countOfDirEntries = buffer.getShort();
- sb.append(" Transaction status: ");
- byte status = buffer.get();
- sb.append(TxUtils.getStatusAsString(status));
- sb.append("\n");
- sb.append(" Heuristic status: ");
- byte heurCode = buffer.get();
- if (heurCode != 0)
- sb.append(TxUtils.getXAErrorCodeAsString(heurCode));
- else
- sb.append("NONE");
- sb.append("\n");
- sb.append(" Locally-detected heuristic hazard: ");
- sb.append((buffer.get() != 0) ? "yes" : "no");
- sb.append("\n");
- sb.append(" Foreign transaction: ");
- boolean foreignTransaction = (buffer.get() != 0);
- sb.append((foreignTransaction) ? "yes" : "no");
- sb.append("\n");
- sb.append((foreignTransaction) ? " Inbound format id: "
- : " Format id: ");
- sb.append(buffer.getInt());
- sb.append("\n");
- gidLen = buffer.getShort();
- sb.append(" Global transaction id: ");
- gid = new byte[gidLen];
- buffer.get(gid);
- sb.append(new String(gid, 0));
- sb.append("\n");
- // Get varField 0
- length = buffer.getShort(recLen - CHKSUM_LEN - SIZEOF_SHORT);
- if (length > 0)
- {
- sb.append(" Inbound branch qualifier: ");
- offset = buffer.getShort(recLen - CHKSUM_LEN - SIZEOF_DIR_ENTRY);
- sb.append(new String(buffer.array(), 0, offset, length));
- sb.append("\n");
- }
- // Get varField 1
- length = buffer.getShort(recLen - CHKSUM_LEN
- - SIZEOF_SHORT
- - SIZEOF_DIR_ENTRY);
- if (length > 0)
- {
- offset = buffer.getShort(recLen - CHKSUM_LEN
- - SIZEOF_DIR_ENTRY
- - SIZEOF_DIR_ENTRY);
- sb.append(" XAResource heuristics:\n");
- for (int i = 0; i < length; i++)
- {
- sb.append(" ");
- heurCode = buffer.get(offset + i);
- sb.append(TxUtils.getXAErrorCodeAsString(heurCode));
- sb.append("\n");
- }
- }
- // Get varField 2, ..., varField N (where N = countOfDirEntries - 1)
- if (countOfDirEntries > 2)
- {
- sb.append(" Remote resource heuristics:\n");
- for (int i = 2; i < countOfDirEntries; i++)
- {
- length = buffer.getShort(recLen - CHKSUM_LEN
- - SIZEOF_SHORT
- - SIZEOF_DIR_ENTRY * i);
- offset = buffer.getShort(recLen - CHKSUM_LEN
- - SIZEOF_DIR_ENTRY
- - SIZEOF_DIR_ENTRY * i);
- heurCode = buffer.get(offset);
- sb.append(" ");
- sb.append(TxUtils.getXAErrorCodeAsString(heurCode));
- sb.append(" - ");
- sb.append(new String(buffer.array(), 0,
- offset + 1, length - 1));
- sb.append("\n");
- }
- }
- break;
- case HEUR_FORGOTTEN:
- sb.append("HEUR_FORGOTTEN\n");
- sb.append("Local transaction id: ");
- sb.append(buffer.getLong(FULL_HEADER_LEN + SIZEOF_BYTE));
- sb.append("\n");
- break;
- default:
- sb.append("INVALID\n");
- break;
- }
- buffer.position(0);
- return sb.toString();
- }
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/recovery/LogRestarter.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/recovery/LogRestarter.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/recovery/LogRestarter.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,119 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.recovery;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.jboss.logging.Logger;
-
-/**
- * This class supports asynchronous restarting of log files. Restarting a log
- * file means overwriting its entire content with null bytes and returning the
- * file to the pool of clean log files maintained by a <code>BatchWriter</code>.
- * A <code>LogRestarter</code> encapsulates a queue of log files to be
- * restarted and implements a background thread that restarts the log files
- * in the queue. Its sole purpose is to avoid the delay of cleaning up a log
- * file.
- *
- * @author <a href="mailto:reverbel at ime.usp.br">Francisco Reverbel</a>
- * @version $Revision$
- */
-class LogRestarter
- implements Runnable
-{
- /**
- * Class <code>Logger</code>, for trace messages.
- */
- private static Logger errorLog = Logger.getLogger(LogRestarter.class);
-
- /** This flag can be set to false to stop the log restarter thread. */
- private boolean running = true;
-
- /** Queue of <code>BatchLog</code> instances to be restarted. */
- private List logsToRestart = new ArrayList();
-
- /**
- * Takes a log file to be asynchronously restarted.
- *
- * @param log a <code>BatchLog</code> instance to be restarted.
- */
- synchronized void add(BatchLog log)
- {
- logsToRestart.add(log);
- notify();
- }
-
- /**
- * Stops the log restarter thread.
- */
- synchronized void stop()
- {
- running = false;
- notify();
- }
-
- /**
- * The log restarter thread body.
- */
- public void run()
- {
- BatchLog log;
-
- while (running)
- {
- synchronized (this)
- {
- if (logsToRestart.size() > 0)
- {
- log = (BatchLog) logsToRestart.remove(0);
- }
- else
- {
- try
- {
- wait();
- }
- catch (InterruptedException e)
- {
- if (!running)
- break;
- }
- continue;
- }
- }
-
- try
- {
- log.restart();
- }
- catch (IOException e)
- {
- errorLog.error("Error cleaning up transaction log "
- + log.getFilename(), e);
- }
- }
-
- }
-
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/recovery/PendingWriteRequest.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/recovery/PendingWriteRequest.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/recovery/PendingWriteRequest.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,216 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.recovery;
-
-import EDU.oswego.cs.dl.util.concurrent.Latch;
-
-import java.nio.ByteBuffer;
-
-/**
- * Represents one pending "write record" operation to be performed on
- * a <code>BatchLog</code>.
- *
- * @author <a href="mailto:bill at jboss.org">Bill Burke</a>
- * @author <a href="mailto:reverbel at ime.usp.br">Francisco Reverbel</a>
- * @version $Revision$
- */
-class PendingWriteRequest
-{
- /**
- * Type of a tx committed or tx prepared record for a transaction that
- * involves multiple TMs.
- */
- static final int TYPE_TX_MULTI_TM = 1;
-
- /**
- * Type of a tx committed record for a transaction that involves a single TM.
- */
- static final int TYPE_TX_SINGLE_TM = 0;
-
- /**
- * Type of an tx end record for a transaction that involves a multiple TMs.
- * There is no tx end record for a transaction that involves a single TM.
- * */
- static final int TYPE_END = -1;
-
- /**
- * A buffer containing the record to be written to a <code>BatchLog</code>.
- */
- private ByteBuffer buffer;
-
- /**
- * The <code>BatchLog</code> to which the record should be written.
- */
- private BatchLog log;
-
- /**
- * A <code>Latch</code> that will be released after the pending write
- * operation is performed. Whoever actually performs the write operation
- * is responsible for releasing this latch.
- */
- private Latch latch;
-
- /**
- * The <code>TxCompletionHandler</code> associated with a commit record or
- * with a prepare record to be written to a log. The two-phase commit
- * implementation should invoke the completion handler at the end of the
- * second phase of the protocol for the transaction that has the pending
- * commit or prepare record.
- */
- private TxCompletionHandler completionHandler;
-
- /**
- * Either contains an exception thrown during an attempt to perform the
- * pending write record operation, or null if no exception was thrown.
- */
- private Exception failure;
-
- /**
- * Indicates the type of the record to be written to a <code>BatchLog</code>.
- * Possible values are <code>TYPE_TX_MULTI_TM</code>,
- * <code>TYPE_TX_SINGLE_TM</code>, and <code>TX_END</code>.
- *
- */
- private int type;
-
- /**
- * Creates a <code>PendingWriteRequest</code> for a commit or prepare
- * record.
- *
- * @param buffer a buffer containing the commit or prepare record
- * @param latch a latch that will be released after the pending write
- * operation is performed
- * @param multiTmTransaction true if the record refers to a transaction
- * that involves multiple TMs (and requires a tx end record),
- * false if the record refers to a transaction that involves
- * a single TM (and requires no tx end record).
- */
- PendingWriteRequest(ByteBuffer buffer,
- Latch latch,
- boolean multiTmTransaction)
- {
- this.buffer = buffer;
- this.latch = latch;
- this.log = null;
- type = (multiTmTransaction) ? TYPE_TX_MULTI_TM : TYPE_TX_SINGLE_TM;
- }
-
- /**
- * Creates a <code>PendingWriteRequest</code> for a tx end record to be
- * written to a given <code>BatchLog</code>. This method takes an argument
- * that speficies the <code>BatchLog</code> because the tx end record for a
- * transaction must be written to the same <code>BatchLog</code> as the
- * transaction's tx committed or tx prepared record.
- *
- * @param buffer a buffer containing the tx end record
- * @param latch a latch that will be released after the pending write
- * operation is performed
- * @param log the <code>BatchLog</code> to which the tx end record should
- * be written.
- */
- PendingWriteRequest(ByteBuffer buffer, Latch latch, BatchLog log)
- {
- this.buffer = buffer;
- this.latch = latch;
- this.log = log;
- type = TYPE_END;
- }
-
- /**
- * Waits until this pending write record is performed. If an exception
- * was thrown while attempting to perform the write record, this method
- * throws a <code>RuntimeException</code> that contains the original
- * exception.
- *
- * @return the completion handler associated with a tx committed or with
- * a tx prepared record.
- */
- TxCompletionHandler waitTilDone()
- {
- try
- {
- latch.acquire();
- if (failure != null)
- throw failure;
- return completionHandler;
- }
- catch (Exception e)
- {
- throw new RuntimeException(e);
- }
- }
-
- /**
- * Gets the buffer containing the record to be written.
- *
- * @return a <code>ByteBuffer</code> instance containing the record.
- */
- ByteBuffer getBuffer()
- {
- return buffer;
- }
-
- /**
- * Gets the type of the record to be written.
- *
- * @return <code>TYPE_TX_MULTI_TM</code>, or
- * <code>TYPE_TX_SINGLE_TM</code>, or <code>TX_END</code>.
- */
- int getType()
- {
- return type;
- }
-
- /**
- * Gets the <code>BatchLog</code> to which the record should be written.
- *
- * @return the <code>BatchLog</code> to which the record should be written.
- */
- BatchLog getLogger()
- {
- return log;
- }
-
- /**
- * Associates a completion handler with the pending tx committed or
- * tx prepared record.
- *
- * @param completionHandler the new completion handler.
- */
- void setCompletionHandler(TxCompletionHandler completionHandler)
- {
- this.completionHandler = completionHandler;
- }
-
- /**
- * Stores an exception thrown during an attempt to perform the pending
- * write operation. The method <code>waitTilDone</code> will throw a
- * a <code>RuntimeException</code> that contains the stored exception.
- *
- * @param failure an exception to be stored.
- */
- void setFailure(Exception failure)
- {
- this.failure = failure;
- }
-
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/recovery/Recoverable.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/recovery/Recoverable.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/recovery/Recoverable.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,43 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.recovery;
-
-import javax.transaction.xa.XAException;
-import javax.transaction.xa.XAResource;
-import javax.transaction.xa.Xid;
-
-/**
- * Interface that gives access to a XA resource at recovery time.
- *
- * @author <a href="mailto:bill at jboss.org">Bill Burke</a>
- * @version $Revision$
- */
-public interface Recoverable
-{
- public String getId();
-
- public XAResource getResource();
-
- public Xid[] scan() throws XAException;
-
- public void cleanupResource();
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/recovery/RecoveryLogReader.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/recovery/RecoveryLogReader.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/recovery/RecoveryLogReader.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,81 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.recovery;
-
-import java.util.List;
-
-/**
- * Interface that gives access to the information in a recovery log file.
- *
- * @author <a href="mailto:bill at jboss.org">Bill Burke</a>
- * @author <a href="mailto:reverbel at ime.usp.br">Francisco Reverbel</a>
- * @version $Revision$
- */
-public interface RecoveryLogReader
-{
- /**
- * Gets the name of the underlying log file.
- *
- * @return the name of the log file.
- */
- String getLogFileName();
-
- /**
- * Gets the branch qualifier string read from the log file.
- *
- * @return the branch qualifier read from the log file.
- */
- String getBranchQualifier();
-
- /**
- * Recovers transaction information from the log file.
- *
- * @param committedSingleTmTransactions a <code>List</code> of
- * <code>LogRecord.Data</code> instances with one element per
- * committed single-TM transaction logged to the log file
- * @param committedMultiTmTransactions a <code>List</code> of
- * <code>LogRecord.Data</code> instances with one element per
- * committed multi-TM transaction that has not yet completed the
- * second phase of the 2PC protocol when the server crashed
- * @param inDoubtTransactions a <code>List</code> of
- * <code>LogRecord.Data</code> instances with one element per
- * foreign transaction that arrived at the server via DTM/OTS
- * context propagation and was in the in-doubt state (i.e.,
- * replied to prepare with a commit vote but has not yet received
- * information on the transaction outcome) when the server crashed
- * @param inDoubtJcaTransactions a <code>List</code> of
- * <code>LogRecord.Data</code> instances with one element per
- * foreign transaction that arrived at the server via JCA
- * transaction inflow and was in the in-doubt state (i.e., replied
- * to prepare with a commit vote and was waiting for information
- * on the transaction outcome) when the server crashed.
- */
- void recover(List committedSingleTmTransactions,
- List committedMultiTmTransactions,
- List inDoubtTransactions,
- List inDoubtJcaTransactions);
-
- /**
- * Removes the underlying log file.
- */
- void finishRecovery();
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/recovery/RecoveryLogger.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/recovery/RecoveryLogger.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/recovery/RecoveryLogger.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,155 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.recovery;
-
-import javax.transaction.xa.Xid;
-
-/**
- * This is the main interface of the recovery logger service.
- *
- * @author <a href="mailto:bill at jboss.org">Bill Burke</a>
- * @author <a href="mailto:reverbel at ime.usp.br">Francisco Reverbel</a>
- * @version $Revision$
- */
-public interface RecoveryLogger
-{
- /**
- * Should be invoked at the end of the voting phase of the two-phase commit
- * protocol for a transaction started at this virtual machine.
- *
- * @param localTransactionId the local id of the transaction
- * @param resources an array of stringfied references to the remote
- * <code>Resource</code> instances that voted commit.
- * @return a handler that should be invoked at the end of the second phase
- * of the two-phase commit protocol for the transaction (if the
- * transaction is not heuristically completed) or after any
- * heuristic decisions are cleared.
- */
- public TxCompletionHandler saveCommitDecision(long localTransactionId,
- String[] resources);
-
- /**
- * Should be invoked at the end of the voting phase of the two-phase commit
- * protocol for a foreign transaction that arrived at this virtual machine
- * in a transaction context propagated along with a remote invocation.
- *
- * @param localTransactionId the local id assigned to the transaction
- * @param inboundFormatId the format id field of the incoming
- * transaction context
- * @param globalTransactionId the global transaction id field of the
- * incoming transaction context
- * @param recoveryCoordinator a stringfied reference to the remote
- * <code>RecoveryCoordinator</code> instance
- * @param resources an array of stringfied references to the remote
- * <code>Resource</code> instances that voted commit.
- * @return a handler that should be invoked at the end of the second phase
- * of the two-phase commit protocol for the transaction (if the
- * transaction is not heuristically completed) or after any
- * heuristic decisions are cleared.
- */
- public TxCompletionHandler savePrepareDecision(long localTransactionId,
- int inboundFormatId,
- byte[] globalTransactionId,
- String recoveryCoordinator,
- String[] resources);
-
- /**
- * Should be invoked at the end of the voting phase of the two-phase commit
- * protocol for a foreign transaction that arrived at this virtual machine
- * via JCA transaction inflow.
- *
- * @param localTransactionId the local id assigned to the transaction
- * @param inboundXid the inbound <code>Xid</code>
- * @param resources an array of stringfied references to the remote
- * <code>Resource</code> instances that voted commit.
- * @return a handler that should be invoked at the end of the second phase
- * of the two-phase commit protocol for the transaction (if the
- * transaction is not heuristically completed) or after any
- * heuristic decisions are cleared.
- */
- public TxCompletionHandler savePrepareDecision(long localTransactionId,
- Xid inboundXid,
- String[] resources);
-
- /**
- * Should be invoked for a heuristically completed transaction, at the end
- * of the second phase of the two-phase commit protocol.
- *
- * @param localTransactionId the local id assigned to the transaction
- * @param foreignTx true for a foreign transaction, false otherwise
- * @param formatId the format id field of the transaction's <code>Xid</code>
- * @param globalTransactionId the global id field of the transaction's
- * <code>Xid</code>
- * @param inboundBranchQualifier the inbound branch qualifier, in the case
- * of a foreign transaction that has been imported via JCA
- * transaction inflow, or null otherwise
- * @param transactionStatus the transaction status (either
- * <code>javax.transaction.Status.STATUS_COMMITTED</code> or
- * <code>javax.transaction.Status.STATUS_ROLLEDBACK</code>)
- * @param heurStatusCode the heuristic status code, which takes the same
- * values as the <code>errorCode</code> field of
- * <code>javax.transaction.xa.XAException</code>
- * @param locallyDetectedHeuristicHazard true if a heuristic hazard was
- * detected locally and is still outstanding
- * @param xaResourceHeuristics array of heuristic status codes for the
- * <code>XAResource</code> that are in heuristic states
- * @param remoteResourceHeuristics array of <code>HeuristicStatus</code>
- * instances for the remote resources that are in heuristic
- * states.
- */
- public void saveHeuristicStatus(long localTransactionId,
- boolean foreignTx,
- int formatId,
- byte[] globalTransactionId,
- byte[] inboundBranchQualifier,
- int transactionStatus,
- int heurStatusCode,
- boolean locallyDetectedHeuristicHazard,
- int[] xaResourceHeuristics,
- HeuristicStatus[] remoteResourceHeuristics);
-
- /**
- * Clears the heuristic status of a heuristically completed transaction.
- *
- * @param localTransactionId the local id assigned to the transaction
- */
- public void clearHeuristicStatus(long localTransactionId);
-
- /**
- * Should be invoked at recovery time to obtain an array of reader objects
- * that access the existing transaction log files.
- *
- * @return an array that contains one <code>RecoveryLogReader</code>
- * instance per transaction log file.
- */
- public RecoveryLogReader[] getRecoveryLogs();
-
- /**
- * Should be invoked at recovery time to obtain an array of reader objects
- * that access the existing heuristic status log files.
- *
- * @return an array that contains one <code>HeuristicStatusLogReader</code>
- * instance per heuristic status log file.
- */
- public HeuristicStatusLogReader[] getHeuristicStatusLogs();
-
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/recovery/RecoveryLoggerInstance.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/recovery/RecoveryLoggerInstance.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/recovery/RecoveryLoggerInstance.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,33 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.recovery;
-
-/**
- * Interface that gives access to a <code>RecoveryLogger</code> instance.
- *
- * @author <a href="mailto:bill at jboss.org">Bill Burke</a>
- * @version $Revision$
- */
-public interface RecoveryLoggerInstance
-{
- RecoveryLogger getInstance();
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/recovery/RecoveryManager.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/recovery/RecoveryManager.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/recovery/RecoveryManager.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,1053 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.recovery;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.transaction.Status;
-import javax.transaction.xa.XAException;
-import javax.transaction.xa.XAResource;
-import javax.transaction.xa.Xid;
-
-import org.jboss.logging.Logger;
-import org.jboss.tm.TxManager;
-import org.jboss.tm.TxUtils;
-import org.jboss.tm.XidFactoryBase;
-
-/**
- * A <code>RecoveryManager</code> object manages the crash recovery process.
- * At recovery time, the <code>RecoveryManagerService</code> creates a
- * <code>RecoveryManager</code> instance that interacts with the
- * <code>RecoveryLogger</code> to read the transaction logs and identify
- * the transactions that were active at the time of the crash. The
- * <code>RecoveryManager</code> knows how to perform crash recovery for
- * transactions involving <code>XAResource</code>s that correspond to
- * <code>Recoverable</code> objects known in advance.
- *
- * @author <a href="mailto:bill at jboss.org">Bill Burke</a>
- * @author <a href="mailto:reverbel at ime.usp.br">Francisco Reverbel</a>
- * @version $Revision$
- */
-public class RecoveryManager
-{
- /**
- * Class <code>Logger</code> for trace messages.
- */
- private static Logger log = Logger.getLogger(RecoveryManager.class.getName());
-
- /**
- * A <code>XAResourceAccess</code> implementation that calls
- * <code>cleanUpResource</code> on a <code>Recoverable</code> instance
- * if the <code>Recoverable</code> will not be used anymore. The
- * last <code>release</code> call on an <code>XAResourceAccess</code>
- * instance closes the underlying <code>XAConnection</code>.
- */
- public static class XAResourceAccessImpl
- implements XAResourceAccess
- {
- private Recoverable recoverable;
- private int refCount;
-
- // not public -- called only by the XAResXids constructor (see below)
- XAResourceAccessImpl(Recoverable recoverable)
- {
- this.recoverable = recoverable;
- refCount = 1;
- }
-
- // not public -- called only by the XAWork constructor
- synchronized XAResourceAccess duplicate()
- {
- refCount++;
- return this;
- }
-
- public synchronized void release()
- {
- if (refCount <= 0)
- log.warn("release called, but refCount=" + refCount +
- ", this=" + this, new Throwable("[Stack trace]"));
-
- if (--refCount == 0)
- recoverable.cleanupResource();
- }
-
- }
-
- /**
- * "Struct class" that groups together a <code>Recoverable</code> object,
- * the <code>XAResource</code> represented by the <code>Recoverable</code>,
- * and a set of <code>Xids</code> that still need to be processed.
- */
- private static class XAResourceXids
- {
- public Recoverable recoverable;
- public XAResource resource;
- public XAResourceAccessImpl resourceAccess;
- public Set xids;
-
- XAResourceXids(Recoverable recoverable)
- {
- this.recoverable = recoverable;
- this.resource = recoverable.getResource();
- // Note that the XAResourceAccess constructor is *not* called if a
- // throwable occurs in recoverable.getResource().
- this.resourceAccess = new XAResourceAccessImpl(recoverable);
- this.xids = new HashSet();
- }
- }
-
- /**
- * This implementation of <code>TxCompletionHandler</code> handles
- * transaction completion for transactions recreated by the recovery
- * process.
- */
- private static class CompletionHandler
- implements TxCompletionHandler
- {
- /**
- * The log reader associated with the transaction whose completion
- * is handled by this <code>CompletionHandler</code>.
- */
- private RecoveryLogReader reader;
-
- /**
- * Number of pending transactions associated with the log reader.
- */
- private int pendingTransactions;
-
- /**
- * Creates a new <code>CompletionHandler</code>.
- *
- * @param reader log reader associated with the transaction whose
- * completion will be handled by the new
- * <code>CompletionHandler</code>
- * @param pendingTransactions number of pending transactions
- * associated with the log reader above.
- */
- CompletionHandler(RecoveryLogReader reader, int pendingTransactions)
- {
- this.reader = reader;
- this.pendingTransactions = pendingTransactions;
- }
-
- /**
- * Signals the end of the two-phase commit protocol for a committed
- * transaction. This method should be invoked when the second phase of the
- * two-phase commit protocol completes successfully.
- *
- * @param localTransactionId the local id of the completed transaction.
- */
- public void handleTxCompletion(long localTransactionId)
- {
- if (--pendingTransactions == 0)
- reader.finishRecovery();
- }
- }
-
- /**
- * The Xid factory used by this <code>RecoveryManager</code>.
- */
- private XidFactoryBase xidFactory;
-
- /**
- * The transaction manager used by this <code>RecoveryManager</code>.
- */
- private TxManager txManager;
-
- /**
- * The recovery logger used by this <code>RecoveryManager</code>.
- */
- private RecoveryLogger recoveryLogger;
-
- /**
- * Constructs a new <code>RecoveryManager</code>.
- *
- * @param xidFactory the Xid factory that will be used by the new
- * <code>RecoveryManager</code>
- * @param txManager the transaction manager that will be used by the new
- * <code>RecoveryManager</code>
- * @param recoveryLogger the recovery logger that will be used by the new
- * <code>RecoveryManager</code>
- */
- public RecoveryManager(XidFactoryBase xidFactory,
- TxManager txManager,
- RecoveryLogger recoveryLogger)
- {
- this.xidFactory = xidFactory;
- this.txManager = txManager;
- this.recoveryLogger = recoveryLogger;
- }
-
- /**
- * Performs crash recovery. This method reads the transaction logs,
- * identifies the transactions that were active at the time of the crash,
- * and performs crash recovery actions for each such transaction, which
- * may involve any subset of the <code>XAResource</code>s associated with
- * a given list of <code>Recoverable</code> objects
- *
- * @param rcoverables a list of <code>Recoverable</code> objects whose
- * <code>XAResource</code>s may be involved in active
- * transactions.
- */
- public void recover(ArrayList recoverables)
- {
- Map heuristicallyCompletedTransactions = new HashMap();
-
- HeuristicStatusLogReader[] heurStatusLogReaders =
- recoveryLogger.getHeuristicStatusLogs();
-
- if (heurStatusLogReaders != null)
- {
- // Get the heuristically completed transactions
- // from the existing heuristic status log files
- for (int i = 0; i < heurStatusLogReaders.length; i++)
- heurStatusLogReaders[i].recover(heuristicallyCompletedTransactions);
-
- // Save the heuristic status of those transactions
- // to the current heuristic status log file
- Iterator heurIt =
- heuristicallyCompletedTransactions.keySet().iterator();
- while (heurIt.hasNext())
- {
- Long localId = (Long) heurIt.next();
- LogRecord.HeurData heurData =
- (LogRecord.HeurData) heuristicallyCompletedTransactions.get(
- localId);
- recoveryLogger.saveHeuristicStatus(
- heurData.localTransactionId,
- heurData.foreignTx,
- heurData.formatId,
- heurData.globalTransactionId,
- heurData.inboundBranchQualifier,
- heurData.transactionStatus,
- heurData.heuristicStatusCode,
- heurData.locallyDetectedHeuristicHazard,
- heurData.xaResourceHeuristics,
- heurData.remoteResourceHeuristics);
- }
-
- // Get rid of the existing heuristic status log files
- for (int i = 0; i < heurStatusLogReaders.length; i++)
- heurStatusLogReaders[i].finishRecovery();
- }
-
- RecoveryLogReader[] readers = recoveryLogger.getRecoveryLogs();
- if (readers == null || readers.length == 0)
- return;
-
- // Obtain the set of branch qualifiers generated by this TM.
- Set readerBranchQualifiers = new HashSet();
- for (int i = 0; i < readers.length; i++)
- {
- String branchQualifier = null;
- try
- {
- branchQualifier = readers[i].getBranchQualifier();
- }
- catch (Exception e)
- {
- log.error("logfile corrupted: "
- + readers[i].getLogFileName(), e);
- }
- readerBranchQualifiers.add(branchQualifier);
- log.info("will recover transactions with branch qualifier " +
- branchQualifier +
- " (logFile: " + readers[i].getLogFileName() + ")");
- }
-
- Map toRecoverMap = new HashMap();
- try
- {
- // Populate a map whose keys are Recoverable ids and whose values are
- // XAResourceXids objects, each of which contains the set of Xids of
- // the active XA transaction branches that involve a given XAResource
- // and that require recovery actions.
- for (int i = 0; i < recoverables.size(); i++)
- {
- Recoverable rec = (Recoverable) recoverables.get(i);
- XAResourceXids xaResXids;
- try
- {
- xaResXids = new XAResourceXids(rec);
- }
- catch (Throwable t)
- {
- throw new RuntimeException("Unable to getResource: "
- + rec.getId()
- + " aborting recovery.", t);
- }
- toRecoverMap.put(rec.getId(), xaResXids);
- try
- {
- xaResXids.xids.addAll(pruneXidList(rec.scan(),
- readerBranchQualifiers,
- rec.getId()));
- }
- catch (XAException e)
- {
- // TODO also, what to do if this fails?
- // Should we go on and still try to recover other resources?
- throw new RuntimeException("Unable to scan: " + rec.getId(), e);
- }
- }
-
- // Perform the recovery actions.
- recover(readers, heuristicallyCompletedTransactions, toRecoverMap);
- }
- finally
- {
- cleanupRecoverables(toRecoverMap.values().iterator());
- }
- }
-
- /**
- * Performs crash recovery using a given array of log readers and a map
- * with information on the active XA transaction branches for which
- * recovery actions must be taken.
- *
- * @param readers an array of transaction log readers
- * @param heuristicallyCompletedTransactions
- * @param toRecoverMap a map whose keys are <code>Recoverable</code> ids
- * and whose values are <code>XAResourceXids<code>
- * objects, each of which contains the set of
- * <code>Xids</code> for the active XA transaction
- * branches that involve a given <code>XAResource<code>
- * and that require recovery actions.
- */
- private void recover(RecoveryLogReader[] readers,
- Map heuristicallyCompletedTransactions,
- Map toRecoverMap)
- {
- boolean presumeRollback = true;
- CorruptedLogRecordException corruptedLogRecordException = null;
-
- // Recreate the pending committed and in-doubt transactions, including the
- // ones that are pending just because they were heuristically completed.
- for (int i = 0; i < readers.length; i++)
- {
- log.info("recovering log file " + readers[i].getLogFileName());
- List committedSingleTmTransactions = new ArrayList();
- List committedMultiTmTransactions = new ArrayList();
- List inDoubtTransactions = new ArrayList();
- List inDoubtJcaTransactions = new ArrayList();
-
- try
- {
- readers[i].recover(committedSingleTmTransactions,
- committedMultiTmTransactions,
- inDoubtTransactions,
- inDoubtJcaTransactions);
- }
- catch (CorruptedLogRecordException e)
- {
- log.trace("reader threw CorruptedLogRecordException with " +
- "disablePresumedRollback=" + e.disablePresumedRollback);
- corruptedLogRecordException = e;
- if (corruptedLogRecordException.disablePresumedRollback)
- presumeRollback = false;
- }
-
- int pendingTransactions = committedSingleTmTransactions.size() +
- committedMultiTmTransactions.size() +
- inDoubtTransactions.size() +
- inDoubtJcaTransactions.size();
-
- if (pendingTransactions == 0)
- readers[i].finishRecovery();
- else
- {
- CompletionHandler completionHandler =
- new CompletionHandler(readers[i], pendingTransactions);
-
- resumePendingTransactions(heuristicallyCompletedTransactions,
- committedSingleTmTransactions,
- committedMultiTmTransactions,
- inDoubtTransactions,
- inDoubtJcaTransactions,
- toRecoverMap,
- completionHandler);
- }
- }
-
- // Recreate the remaining heuristically completed transactions
- // (these transactions are in the rolledback state).
- Iterator heurIt = heuristicallyCompletedTransactions.keySet().iterator();
- while (heurIt.hasNext())
- {
- Long localId = (Long) heurIt.next();
- LogRecord.HeurData heurData =
- (LogRecord.HeurData) heuristicallyCompletedTransactions.get(localId);
- heurIt.remove(); // heuristicallyCompletedTransactions.remove(localId)
- byte[] globalId = heurData.globalTransactionId;
- List xaResourcesWithHeuristics = getXAWork(globalId, toRecoverMap);
- txManager.recreateTransaction(heurData,
- xaResourcesWithHeuristics,
- null /* no completion handler */);
- }
-
- if (!presumeRollback)
- {
- log.info("PRESUMED ROLLBACK IS DISABLED DUE TO LOG FILE CORRUPTION.");
- }
-
- // Rollback the transactions that remained in the toRecoverMap.
- // (This is presumed rollback.)
- Iterator rit = toRecoverMap.values().iterator();
- while (rit.hasNext())
- {
- XAResourceXids xaResXids = (XAResourceXids) rit.next();
- Iterator it = xaResXids.xids.iterator();
- while (it.hasNext())
- {
- Xid xid = (Xid) it.next();
- if (!presumeRollback)
- {
- log.info("WOULD ROLLBACK " + xidFactory.toString(xid) +
- " ON RECOVERABLE XAResource " +
- xaResXids.recoverable.getId() +
- ", BUT PRESUMED ROLLBACK IS DISABLED");
- }
- else
- {
- try
- {
- xaResXids.resource.rollback(xid);
- log.info("rolledback " + xidFactory.toString(xid) +
- " on recoverable XAResource " +
- xaResXids.recoverable.getId());
- }
- catch (XAException e)
- {
- log.warn("XAException in recover (when rolling back " +
- "res " + xaResXids.recoverable.getId() + ", xid=" +
- xidFactory.toString(xid) + "): errorCode="
- + TxUtils.getXAErrorCodeAsString(e.errorCode), e);
- // TODO: check the errorCode and retry the rollback if
- // XAER_RMFAIL or XAER_RMFAIL.
- }
- }
- }
- }
-
- if (corruptedLogRecordException != null)
- throw corruptedLogRecordException;
- }
-
- /**
- * Resumes the pending transactions specified by the <code>List</code>
- * arguments.
- *
- * @param committedSingleTmTransactions a list of
- * <code>LogRecord.Data</code> objects
- * for the committed single-TM
- * transactions
- * @param committedMultiTmTransactions a list of <code>LogRecord.Data</code>
- * objects for the committed multi-TM
- * transactions
- * @param inDoubtTransactions a list of <code>LogRecord.Data</code> objects
- * for the in-doubt transactions that entered
- * this virtual machine in transaction contexts
- * propagated along with remote method invocations
- * @param inDoubtJcaTransactions a list of <code>LogRecord.Data</code> objects
- * for the in-doubt transactions that entered
- * this virtual machine through JCA transaction
- * inflow
- * @param toRecoverMap a map whose keys are <code>Recoverable</code> ids and
- * whose values are <code>XAResourceXids<code> objects,
- * each of which contains the set of <code>Xids</code>
- * for all active XA transaction branches that involve
- * a given <code>XAResource<code> and that require
- * recovery actions
- * @param completionHandler a <code>TxCompletionHandler</code> that handles
- * the completion of all transactions specified by
- * the preceding arguments.
- */
- private void resumePendingTransactions(Map heuristicallyCompletedTransactions,
- List committedSingleTmTransactions,
- List committedMultiTmTransactions,
- List inDoubtTransactions,
- List inDoubtJcaTransactions,
- Map toRecoverMap,
- TxCompletionHandler completionHandler)
- {
- Iterator it;
- LogRecord.Data data;
- LogRecord.HeurData heurData;
-
- it = committedSingleTmTransactions.iterator();
- while (it.hasNext())
- {
- data = (LogRecord.Data) it.next();
- byte[] globalId = data.globalTransactionId;
- Long localId = new Long(data.localTransactionId);
- heurData =
- (LogRecord.HeurData)heuristicallyCompletedTransactions.get(localId);
-
- if (heurData != null)
- heuristicallyCompletedTransactions.remove(localId);
-
- if (heurData != null && !heurData.locallyDetectedHeuristicHazard)
- {
- List xaResourcesWithHeuristics = getXAWork(globalId, toRecoverMap);
- txManager.recreateTransaction(heurData,
- xaResourcesWithHeuristics,
- completionHandler);
- }
- else
- {
- // Either heurData is null or it has a
- // locally-detected heuristic hazard.
-
- List pendingXAWorkList = commitXAWork(globalId, toRecoverMap);
- if (pendingXAWorkList.isEmpty())
- {
- if (heurData == null)
- {
- completionHandler.handleTxCompletion(data.localTransactionId);
- }
- else
- {
- // just the locally-detected heuristic hazard
- txManager.recreateTransaction(heurData,
- pendingXAWorkList,
- completionHandler);
- }
- }
- else
- {
- txManager.recreateTransaction(data.localTransactionId,
- pendingXAWorkList,
- completionHandler,
- heurData);
- }
- }
- }
-
- it = committedMultiTmTransactions.iterator();
- while (it.hasNext())
- {
- data = (LogRecord.Data) it.next();
- byte[] globalId = data.globalTransactionId;
- Long localId = new Long(data.localTransactionId);
- heurData =
- (LogRecord.HeurData)heuristicallyCompletedTransactions.get(localId);
-
- if (heurData != null)
- heuristicallyCompletedTransactions.remove(localId);
-
- if (heurData != null && !heurData.locallyDetectedHeuristicHazard)
- {
- List xaResourcesWithHeuristics = getXAWork(globalId, toRecoverMap);
- txManager.recreateTransaction(heurData,
- xaResourcesWithHeuristics,
- completionHandler);
- }
- else
- {
- // Either heurData is null or it has a
- // locally-detected heuristic hazard.
-
- List pendingXAWorkList = commitXAWork(globalId, toRecoverMap);
- txManager.recreateTransaction(data.localTransactionId,
- pendingXAWorkList,
- data.resources,
- completionHandler,
- heurData);
- }
- }
-
- it = inDoubtTransactions.iterator();
- while (it.hasNext())
- {
- data = (LogRecord.Data) it.next();
- byte[] globalId = data.globalTransactionId;
- Long localId = new Long(data.localTransactionId);
- heurData =
- (LogRecord.HeurData)heuristicallyCompletedTransactions.get(localId);
-
- if (heurData != null)
- heuristicallyCompletedTransactions.remove(localId);
-
- if (heurData != null && !heurData.locallyDetectedHeuristicHazard)
- {
- heuristicallyCompletedTransactions.remove(localId);
- List xaResourcesWithHeuristics = getXAWork(globalId, toRecoverMap);
- txManager.recreateTransaction(heurData,
- xaResourcesWithHeuristics,
- completionHandler);
- }
- else
- {
- // Either heurData is null or it has a
- // locally-detected heuristic hazard.
-
- if (heurData == null)
- {
- List preparedXAWorkList = getXAWork(globalId, toRecoverMap);
- txManager.recreateTransaction(data.localTransactionId,
- data.inboundFormatId,
- data.globalTransactionId,
- data.recoveryCoordinator,
- preparedXAWorkList,
- data.resources,
- completionHandler,
- null);
- }
- else
- {
- // locally-detected heuristic hazard
- if (heurData.transactionStatus == Status.STATUS_COMMITTING)
- {
- List pendingXAWorkList = commitXAWork(globalId, toRecoverMap);
- txManager.recreateTransaction(data.localTransactionId,
- data.inboundFormatId,
- data.globalTransactionId,
- data.recoveryCoordinator,
- pendingXAWorkList,
- data.resources,
- completionHandler,
- heurData);
- }
- else if (heurData.transactionStatus == Status.STATUS_ROLLING_BACK)
- {
- List pendingXAWorkList =
- rollbackXAWork(globalId, toRecoverMap);
- txManager.recreateTransaction(data.localTransactionId,
- data.inboundFormatId,
- data.globalTransactionId,
- data.recoveryCoordinator,
- pendingXAWorkList,
- data.resources,
- completionHandler,
- heurData);
- }
- else
- {
- log.warn("Cannot recover tx=" + toString() +
- "\nInconsistent state",
- new Throwable("[Stack trace]"));
- }
- }
- }
- }
-
- it = inDoubtJcaTransactions.iterator();
- while (it.hasNext())
- {
- data = (LogRecord.Data) it.next();
- byte[] globalId = data.globalTransactionId;
- Long localId = new Long(data.localTransactionId);
- heurData =
- (LogRecord.HeurData)heuristicallyCompletedTransactions.get(localId);
-
- if (heurData != null)
- heuristicallyCompletedTransactions.remove(localId);
-
- if (heurData != null && !heurData.locallyDetectedHeuristicHazard)
- {
- List xaResourcesWithHeuristics = getXAWork(globalId, toRecoverMap);
- txManager.recreateTransaction(heurData,
- xaResourcesWithHeuristics,
- completionHandler);
- }
- else
- {
- // Either heurData is null or it has a
- // locally-detected heuristic hazard.
-
- List preparedXAWorkList = getXAWork(globalId, toRecoverMap);
- if (heurData == null)
- {
- txManager.recreateTransaction(data.localTransactionId,
- data.inboundFormatId,
- data.globalTransactionId,
- data.inboundBranchQualifier,
- preparedXAWorkList,
- data.resources,
- completionHandler,
- null);
- }
- else
- {
- // locally-detected heuristic hazard
- if (heurData.transactionStatus == Status.STATUS_COMMITTING)
- {
- List pendingXAWorkList = commitXAWork(globalId, toRecoverMap);
- txManager.recreateTransaction(data.localTransactionId,
- data.inboundFormatId,
- data.globalTransactionId,
- data.inboundBranchQualifier,
- pendingXAWorkList,
- data.resources,
- completionHandler,
- heurData);
- }
- else if (heurData.transactionStatus == Status.STATUS_ROLLING_BACK)
- {
- List pendingXAWorkList =
- rollbackXAWork(globalId, toRecoverMap);
- txManager.recreateTransaction(data.localTransactionId,
- data.inboundFormatId,
- data.globalTransactionId,
- data.inboundBranchQualifier,
- pendingXAWorkList,
- data.resources,
- completionHandler,
- heurData);
- }
- else
- {
- log.warn("Cannot recover tx=" + toString() +
- "\nInconsistent state",
- new Throwable("[Stack trace]"));
- }
- }
- }
- }
- }
-
- /**
- * Commits the XA work associated with a given global transaction id. This
- * method receives a <code>toRecoverMap</code> whose values are
- * <code>XAResourceXids<code> objects that contain the <code>Xids</code>
- * of all active XA transaction branches that require recovery actions.
- * It removes from the <code>toRecoverMap</code> all <code>Xids</code>
- * that correspond to the XA work committed (those associated with the
- * specified <code>globalId</code>).
- *
- * @param globalId the global transaction id associated with the work to
- * commit
- * @param toRecoverMap a map whose keys are <code>Recoverable</code> ids and
- * whose values are <code>XAResourceXids<code> objects,
- * each of which contains the set of <code>Xids</code>
- * for all active XA transaction branches that involve
- * a given <code>XAResource<code> and that require
- * recovery actions
- * @return a "pending work" list containing <code>XAWork</code> instances
- * describing the work that should have been committed, but could
- * not be committed due to transient problems. The caller should
- * try to commit the pending work again, at a later time.
- */
- private List commitXAWork(byte[] globalId, Map toRecoverMap)
- {
- log.info("*** trying to complete XA work with globalId " +
- new String(globalId).trim());
- globalId = pad(globalId);
- List pendingXAWorkList = new ArrayList();
- Iterator rit = toRecoverMap.values().iterator();
- while (rit.hasNext())
- {
- XAResourceXids toRecover = (XAResourceXids) rit.next();
- log.info(" looking at resource " + toRecover.recoverable.getId());
-
- Iterator resXidIt = toRecover.xids.iterator();
- while (resXidIt.hasNext())
- {
- Xid resXid = (Xid) resXidIt.next();
- byte[] resGlobalId = pad(resXid.getGlobalTransactionId());
- if (!Arrays.equals(globalId, resGlobalId))
- continue;
- try
- {
- toRecover.resource.commit(resXid, false);
- log.info(" committed: " + resXid);
- }
- catch (XAException e)
- {
- switch (e.errorCode)
- {
- case XAException.XA_HEURCOM:
- // Ignore this exception, as the the heuristic outcome
- // is the one we wanted anyway.
- log.trace("commitXAWork ignored XAException.XA_HEURCOM", e);
- try
- {
- toRecover.resource.forget(resXid);
- }
- catch (XAException xae)
- {
- log.warn("XAException in commitXAWork (when forgetting " +
- "XA_HEURCOM): errorCode=" +
- TxUtils.getXAErrorCodeAsString(xae.errorCode),
- xae);
- }
- break;
- case XAException.XA_HEURRB:
- case XAException.XA_HEURMIX:
- case XAException.XA_HEURHAZ:
- log.warn("Heuristic XAException in commitXAWork: errorCode=" +
- TxUtils.getXAErrorCodeAsString(e.errorCode) +
- "\nWill deal with the heuristic later", e);
- XAWork postponedWork = new XAWork(toRecover.resource,
- resXid,
- toRecover.resourceAccess);
- pendingXAWorkList.add(postponedWork);
- break;
- case XAException.XAER_RMERR:
- log.warn("Unexpected XAException in commitXAWork: errorCode="
- + TxUtils.getXAErrorCodeAsString(e.errorCode), e);
- break;
- case XAException.XAER_RMFAIL:
- case XAException.XA_RETRY:
- log.warn("XAException in commitXAWork: errorCode=" +
- TxUtils.getXAErrorCodeAsString(e.errorCode) +
- "\nWill attempt to commit the XAResource later", e);
- XAWork pendingXAWork = new XAWork(toRecover.resource,
- resXid,
- toRecover.resourceAccess);
- pendingXAWorkList.add(pendingXAWork);
- break;
- case XAException.XAER_NOTA:
- case XAException.XAER_INVAL:
- case XAException.XAER_PROTO:
- default:
- // This should never happen!
- log.warn("Could not recover from unexpected XAException: " +
- " errorCode=" +
- TxUtils.getXAErrorCodeAsString(e.errorCode), e);
- break;
- }
- }
- finally
- {
- resXidIt.remove(); // remove resXid from toRecover.xids
- }
- }
- if (toRecover.xids.isEmpty())
- rit.remove(); // remove toRecover from toRecoverMap
- }
- return pendingXAWorkList;
- }
-
- private List rollbackXAWork(byte[] globalId, Map toRecoverMap)
- {
- log.info("*** trying to rollback XA work with globalId " +
- new String(globalId).trim());
- globalId = pad(globalId);
- List pendingXAWorkList = new ArrayList();
- Iterator rit = toRecoverMap.values().iterator();
- while (rit.hasNext())
- {
- XAResourceXids toRecover = (XAResourceXids) rit.next();
- log.info(" looking at resource " + toRecover.recoverable.getId());
-
- Iterator resXidIt = toRecover.xids.iterator();
- while (resXidIt.hasNext())
- {
- Xid resXid = (Xid) resXidIt.next();
- byte[] resGlobalId = pad(resXid.getGlobalTransactionId());
- if (!Arrays.equals(globalId, resGlobalId))
- continue;
- try
- {
- toRecover.resource.rollback(resXid);
- log.info(" rolledback: " + resXid);
- }
- catch (XAException e)
- {
- switch (e.errorCode)
- {
- case XAException.XA_HEURRB:
- // Ignore this exception, as the the heuristic outcome
- // is the one we wanted anyway.
- log.trace("rollbackXAWork ignored XAException.XA_HEURRB", e);
- try
- {
- toRecover.resource.forget(resXid);
- }
- catch (XAException xae)
- {
- log.warn("XAException in rollbackXAWork (when forgetting "
- + "XA_HEURRB): errorCode=" +
- TxUtils.getXAErrorCodeAsString(xae.errorCode),
- xae);
- }
- break;
- case XAException.XA_HEURCOM:
- case XAException.XA_HEURMIX:
- case XAException.XA_HEURHAZ:
- log.warn("Heuristic XAException in rollbackXAWork: errorCode="
- + TxUtils.getXAErrorCodeAsString(e.errorCode) +
- "\nWill deal with the heuristic later", e);
- XAWork postponedWork = new XAWork(toRecover.resource,
- resXid,
- toRecover.resourceAccess);
- pendingXAWorkList.add(postponedWork);
- break;
- case XAException.XAER_RMERR:
- log.warn("Unexpected XAException in rollbackXAWork: " +
- "errorCode="
- + TxUtils.getXAErrorCodeAsString(e.errorCode), e);
- break;
- case XAException.XAER_RMFAIL:
- case XAException.XA_RETRY:
- log.warn("XAException in rollbackXAWork: errorCode=" +
- TxUtils.getXAErrorCodeAsString(e.errorCode) +
- "\nWill attempt to rollback the XAResource later", e);
- XAWork pendingXAWork = new XAWork(toRecover.resource,
- resXid,
- toRecover.resourceAccess);
- pendingXAWorkList.add(pendingXAWork);
- break;
- case XAException.XAER_NOTA:
- case XAException.XAER_INVAL:
- case XAException.XAER_PROTO:
- default:
- // This should never happen!
- log.warn("Could not recover from unexpected XAException: " +
- " errorCode=" +
- TxUtils.getXAErrorCodeAsString(e.errorCode), e);
- break;
- }
- }
- finally
- {
- resXidIt.remove(); // remove resXid from toRecover.xids
- }
- }
- if (toRecover.xids.isEmpty())
- rit.remove(); // remove toRecover from toRecoverMap
- }
- return pendingXAWorkList;
- }
-
- /**
- * Extracts from a <code>toRecoverMap</code> all the XA work that is
- * associated with a given global transaction id. This method scans
- * the <code>toRecoverMap</code> and builds a list of <code>XAWork</code>
- * instances whose <code>Xids</code> contain the specified global id.
- * It removes all those <code>Xids</code> from the the
- * <code>toRecoverMap</code>.
- *
- * @param globalId the global transaction id
- * @param toRecoverMap a map whose keys are <code>Recoverable</code> ids
- * and whose values are <code>XAResourceXids<code>
- * objects, each of which contains the set of
- * <code>Xids</code> for the active XA transaction
- * branches that involve a given <code>XAResource<code>
- * and that require recovery actions.
- * @return a <code>List</code> of <code>XAWork</code> instances with
- * <code>Xid</code> fields that were taken from the
- * <code>toRecoverMap</code> and that contain the specified global
- * transaction id.
- */
- private List getXAWork(byte[] globalId, Map toRecoverMap)
- {
- log.info("*** getting XA work with globalId " +
- new String(globalId).trim());
- globalId = pad(globalId);
- List xaWorkList = new ArrayList();
- Iterator rit = toRecoverMap.values().iterator();
- while (rit.hasNext())
- {
- XAResourceXids toRecover = (XAResourceXids) rit.next();
- log.info(" looking at resource " + toRecover.recoverable.getId());
-
- Iterator resXidIt = toRecover.xids.iterator();
- while (resXidIt.hasNext())
- {
- Xid resXid = (Xid) resXidIt.next();
- byte[] resGlobalId = pad(resXid.getGlobalTransactionId());
- if (!Arrays.equals(globalId, resGlobalId))
- continue;
-
- XAWork preparedXAWork = new XAWork(toRecover.resource,
- resXid,
- toRecover.resourceAccess);
- xaWorkList.add(preparedXAWork);
- resXidIt.remove(); // remove resXid from toRecover.xids
- }
- }
- return xaWorkList;
- }
-
- /**
- * Takes an iterator for a collection of <code>XAResourceXids</code>
- * instances and cleans up every <code>Recoverable</code> in the
- * <code>recoverable</code> field of an element of the collection.
- */
- private void cleanupRecoverables(Iterator it)
- {
- while (it.hasNext())
- {
- XAResourceXids xaResXids = (XAResourceXids) it.next();
- try
- {
- xaResXids.resourceAccess.release();
- }
- catch (Exception ignored)
- {
- }
- }
- }
-
- /**
- * Filters out every xid whose branch qualifier field was not generated by
- * transaction manager. This is to avoid rolling back transaction branches
- * that are not ours.
- */
- private List pruneXidList(Xid[] xids,
- Set branchQualifiers,
- String resourceName)
- {
- ArrayList list = new ArrayList();
- for (int i = 0; i < xids.length; i++)
- {
- byte[] branchQual = xids[i].getBranchQualifier();
- String baseBranchQual = xidFactory.getBaseBranchQualifier(branchQual);
- if (branchQualifiers.contains(baseBranchQual))
- {
- list.add(xids[i]);
- log.info("Adding xid " + xidFactory.toString(xids[i]) +
- " to pruned Xid list for " + resourceName);
-
- }
- }
- return list;
- }
-
- /**
- * Pads a byte array with null bytes so that the length of the padded
- * array is <code>Xid.MAXGTRIDSIZE</code>. Called before comparing
- * global transaction ids.
- *
- */
- private byte[] pad(byte[] globalId)
- {
- if (globalId.length < Xid.MAXGTRIDSIZE)
- {
- byte[] bytes = new byte[Xid.MAXGTRIDSIZE];
- System.arraycopy(globalId, 0, bytes, 0, globalId.length);
- globalId = bytes;
- }
- return globalId;
- }
-
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/recovery/RecoveryManagerService.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/recovery/RecoveryManagerService.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/recovery/RecoveryManagerService.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,183 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.recovery;
-
-import java.util.ArrayList;
-
-import javax.management.Notification;
-import javax.management.NotificationFilter;
-import javax.management.NotificationListener;
-import javax.management.ObjectName;
-
-import org.jboss.system.ServiceMBeanSupport;
-import org.jboss.system.server.Server;
-import org.jboss.system.server.ServerImplMBean;
-import org.jboss.tm.TxManager;
-import org.jboss.tm.XidFactoryMBean;
-
-/**
- * Service MBean that manages crash recovery.
- *
- * @author <a href="mailto:bill at jboss.org">Bill Burke</a>
- * @version $Revision$
- */
-public class RecoveryManagerService
- extends ServiceMBeanSupport
- implements NotificationListener,
- RecoveryManagerServiceMBean
-{
- private ObjectName xidFactory;
- private ObjectName txManager;
- private RecoveryLogger recoveryLogger;
- private XidFactoryMBean xidFactoryObj;
- private TxManager txManagerObj;
- private ArrayList xaResourceManagers = new ArrayList();
-
- // TODO make pluggable
- private RecoveryManager recoveryManager;
-
- // ServiceMBeanSupport overrides ---------------------------------
-
- /**
- * @see org.jboss.system.ServiceMBeanSupport#startService()
- */
- protected void startService() throws Exception
- {
- super.startService();
- xidFactoryObj =
- (XidFactoryMBean) getServer().getAttribute(xidFactory, "Instance");
- txManagerObj =
- (TxManager) getServer().getAttribute(txManager, "TransactionManager");
- txManagerObj.setRecoveryLogger(recoveryLogger);
-
- NotificationFilter filter = new NotificationFilter()
- {
- private static final long serialVersionUID = 1L;
-
- public boolean isNotificationEnabled(Notification n)
- {
- return n.getType().equals(Server.START_NOTIFICATION_TYPE);
- }
- };
-
- this.getServer().addNotificationListener(ServerImplMBean.OBJECT_NAME,
- this,
- filter,
- null);
- }
-
- /**
- * @see org.jboss.system.ServiceMBeanSupport#stopService()
- */
- protected void stopService() throws Exception
- {
- super.stopService();
- }
-
- // NotificationListener implementation ---------------------------
-
- /**
- * @see javax.management.NotificationListener#handleNotification(
- * javax.management.Notification, java.lang.Object)
- */
- public void handleNotification(Notification notification, Object handback)
- {
- log.info("RECEIVED STARTUP NOTIFICATION");
- if (/* resources.size() > 0 && */ recoveryLogger != null)
- {
- recover();
- }
- txManagerObj.clearRecoveryPending();
- }
-
- // RecoveryManagerServiceMBean implementation --------------------
-
- /**
- * @see org.jboss.tm.recovery.RecoveryManagerServiceMBean#getXidFactory()
- */
- public ObjectName getXidFactory()
- {
- return xidFactory;
- }
-
- /**
- * @see org.jboss.tm.recovery.RecoveryManagerServiceMBean#setXidFactory(
- * javax.management.ObjectName)
- */
- public void setXidFactory(ObjectName xidFactory)
- {
- this.xidFactory = xidFactory;
- }
-
- /**
- * @see org.jboss.tm.recovery.RecoveryManagerServiceMBean#getTransactionManager()
- */
- public ObjectName getTransactionManager()
- {
- return txManager;
- }
-
- /**
- * @see org.jboss.tm.recovery.RecoveryManagerServiceMBean#setTransactionManager(
- * javax.management.ObjectName)
- */
- public void setTransactionManager(ObjectName txManager)
- {
- this.txManager = txManager;
- }
-
- /**
- * @see org.jboss.tm.recovery.RecoveryManagerServiceMBean#setRecoveryLogger(
- * org.jboss.tm.recovery.RecoveryLoggerInstance)
- */
- public void setRecoveryLogger(RecoveryLoggerInstance recoveryLogger)
- {
- this.recoveryLogger = recoveryLogger.getInstance();
- }
-
- /**
- * @see org.jboss.tm.recovery.RecoveryManagerServiceMBean#recover()
- */
- public void recover()
- {
- try
- {
- recoveryManager =
- new RecoveryManager(xidFactoryObj, txManagerObj, recoveryLogger);
- recoveryManager.recover(xaResourceManagers);
- }
- catch (Exception e)
- {
- log.error("Unable to recover", e);
- }
- }
-
- /**
- * @see org.jboss.tm.recovery.RecoveryManagerServiceMBean#registerRecoverable(
- * org.jboss.tm.recovery.Recoverable)
- */
- public void registerRecoverable(Recoverable recoverable)
- {
- xaResourceManagers.add(recoverable);
- }
-
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/recovery/RecoveryManagerServiceMBean.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/recovery/RecoveryManagerServiceMBean.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/recovery/RecoveryManagerServiceMBean.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,84 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.recovery;
-
-import javax.management.ObjectName;
-
-import org.jboss.system.ServiceMBean;
-
-/**
- * MBean interface of the recovery manager service.
- *
- * @author <a href="mailto:bill at jboss.org">Bill Burke</a>
- * @version $Revision$
- */
-public interface RecoveryManagerServiceMBean
- extends ServiceMBean
-{
- /**
- * Gets the Xid factory's object name.
- *
- * @return the Xid factory's object name.
- */
- ObjectName getXidFactory();
-
- /**
- * Sets the Xid factory's object name.
- *
- * @param xidFactory the Xid factory's object name.
- */
- void setXidFactory(ObjectName xidFactory);
-
- /**
- * Gets the transaction manager's object name.
- *
- * @return the transaction manager's object name.
- */
- ObjectName getTransactionManager();
-
- /**
- * Sets the transaction manager's object name.
- *
- * @param txManager the transaction manager's object name.
- */
- void setTransactionManager(ObjectName txManager);
-
- /**
- * Sets the recovery logger.
- *
- * @param recoveryLogger a <code>RecoveryLoggerInstance</code>.
- */
- void setRecoveryLogger(RecoveryLoggerInstance recoveryLogger);
-
- /**
- * Registers a <code>Recoverable</code> instance with the recovery manager
- * service.
- *
- * @param recoverable the <code>Recoverable</code> instance to be registered.
- */
- void registerRecoverable(Recoverable recoverable);
-
- /**
- * Performs crash recovery.
- */
- void recover();
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/recovery/RecoveryTestingException.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/recovery/RecoveryTestingException.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/recovery/RecoveryTestingException.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,53 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.recovery;
-
-/**
- * This exception is used by the recovery testing framework to force the TM to abort at
- * certain points so that recovery logging can be tested.
- *
- * @author <a href="mailto:bill at jboss.org">Bill Burke</a>
- * @version $Revision$
- */
-public class RecoveryTestingException extends RuntimeException
-{
- private static final long serialVersionUID = 1L;
-
- public RecoveryTestingException()
- {
- }
-
- public RecoveryTestingException(String message)
- {
- super(message);
- }
-
- public RecoveryTestingException(String message, Throwable cause)
- {
- super(message, cause);
- }
-
- public RecoveryTestingException(Throwable cause)
- {
- super(cause);
- }
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/recovery/SimpleHeuristicStatusLogReader.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/recovery/SimpleHeuristicStatusLogReader.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/recovery/SimpleHeuristicStatusLogReader.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,155 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.recovery;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.channels.FileChannel;
-import java.util.Map;
-
-/**
- * Simple implementation of <code>HeuristicStatusLogReader</code> used at
- * recovery time. The <code>BatchRecoveryLogger</code>'s implementation of
- * method <code>getHeuristicStatusLogs()</code> instantiates
- * <code>SimpleHeuristicStatusLogReader</code>s for the existing heuristic
- * status log files. It returns an array containing those readers, which the
- * recovery manager uses to get information on heuristically completed
- * transactions.
- *
- * @author <a href="mailto:reverbel at ime.usp.br">Francisco Reverbel</a>
- * @version $Revision$
- */
-public class SimpleHeuristicStatusLogReader
- implements HeuristicStatusLogReader
-{
- /** The underlying heuristic status log file. */
- private File logFile;
-
- /**
- * Constructs a <code>SimpleHeuristicStatusLogReader</code>.
- *
- * @param logFile the heuristic status log file to read.
- */
- public SimpleHeuristicStatusLogReader(File logFile)
- {
- this.logFile = logFile;
- }
-
- /**
- * Gets the name of the heuristic status log file.
- *
- * @return the name of the heuristic status log file.
- */
- public String getLogFileName()
- {
- return logFile.toString();
- }
-
- /**
- * Recovers information on heuristically completed transactions from
- * the heuristic status log file.
- *
- * @param heuristicallyCompletedTransactions a <code>Map</code> to which
- * this method will one entry per heuristically completed
- * transaction. The map keys are <code>Long</code> values
- * containing local transaction ids. The map values are
- * <code>LogRecord.HeurData</code> objects with information
- * on heuristically completed transactions.
- */
- public void recover(Map heuristicallyCompletedTransactions)
- {
- FileInputStream fis;
-
- try
- {
- fis = new FileInputStream(logFile);
-
- }
- catch (IOException e)
- {
- throw new RuntimeException(e);
- }
-
- try
- {
- if (fis.available() < LogRecord.FULL_HEADER_LEN)
- return; // TODO: perhaps thrown an exception in this case?
-
- FileChannel channel = fis.getChannel();
- ByteBuffer buf = ByteBuffer.allocate(LogRecord.FULL_HEADER_LEN);
- channel.read(buf);
-
- int len = LogRecord.getNextRecordLength(buf, 0);
- LogRecord.HeurData data = new LogRecord.HeurData();
-
- while (len > 0)
- {
- buf = ByteBuffer.allocate(len + LogRecord.FULL_HEADER_LEN);
- if (channel.read(buf) < len)
- break; // TODO: throw an exception or log something
- buf.flip();
- LogRecord.getHeurData(buf, len, data);
- switch (data.recordType)
- {
- case LogRecord.HEUR_STATUS:
- heuristicallyCompletedTransactions.put(
- new Long(data.localTransactionId),
- data);
- break;
-
- case LogRecord.HEUR_FORGOTTEN:
- heuristicallyCompletedTransactions.remove(
- new Long(data.localTransactionId));
- break;
-
- default:
- // TODO: log something
- break;
- }
- len = LogRecord.getNextRecordLength(buf, len);
- }
- }
- catch (IOException ignore)
- {
- }
- try
- {
- fis.close();
- }
- catch (IOException e)
- {
- throw new RuntimeException(e);
- }
-
- }
-
- /**
- * Removes the heuristic status log file.
- */
- public void finishRecovery()
- {
- logFile.delete();
- }
-
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/recovery/TransactionCompletionLogger.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/recovery/TransactionCompletionLogger.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/recovery/TransactionCompletionLogger.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,73 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.recovery;
-
-import java.nio.ByteBuffer;
-
-/**
- * This <code>TxCompletionHandler</code> implementation writes
- * <code>TX_END</code> records to a <code>BatchLog</code>. At transaction
- * completion, a <code>TX_END</code> record is written out to the
- * <code>BatchLog</code>.
- *
- * @author <a href="mailto:reverbel at ime.usp.br">Francisco Reverbel</a>
- * @version $Revision$
- */
-class TransactionCompletionLogger implements TxCompletionHandler
-{
- /** The underlying <code>BatchLog</code> instance. */
- private BatchLog log;
-
- /**
- * Constructs a <code>TransactionCompletionLogger</code> that writes
- * <code>TX_END</code> records to a given <code>BatchLog</code>.
- *
- * @param log the <code>BatchLog</code> to which <code>TX_END</code>
- * records will be written out.
- */
- TransactionCompletionLogger(BatchLog log)
- {
- this.log = log;
- }
-
- /**
- * Signals the end of the two-phase commit protocol for a committed
- * transaction. This method should be invoked when the second phase of the
- * two-phase commit protocol completes successfully and no heuristic
- * decisions were made. In the case of a heuristically committed transaction,
- * this method should not be invoked at the end of the second phase of the
- * two-phase commit protocol. Instead, the <code>handleTxCompletion</code>
- * call should be postponed until the heuristic outcome is forgotten.
- *
- * This implementation writes to the <code>BatchLog</code> a
- * <code>TX_END</code> record for the transaction.
- *
- * @param localTransactionId the local id of the completed transaction.
- */
- public void handleTxCompletion(long localTransactionId)
- {
- ByteBuffer buffer = LogRecord.createTxEndRecord(localTransactionId);
- BatchWriter writer = log.getBatchWriter();
- writer.addBatch(buffer, log);
- }
-
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/recovery/TxCompletionHandler.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/recovery/TxCompletionHandler.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/recovery/TxCompletionHandler.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,46 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.recovery;
-
-/**
- * Interface of an object that should be invoked at transaction completion.
- *
- * @author <a href="mailto:bill at jboss.org">Bill Burke</a>
- * @author <a href="mailto:reverbel at ime.usp.br">Francisco Reverbel</a>
- * @version $Revision$
- */
-public interface TxCompletionHandler
-{
-
- /**
- * Signals the end of the two-phase commit protocol for a committed
- * transaction. This method should invoked when the second phase of the
- * two-phase commit protocol completes successfully and no heuristic
- * decisions were made. In the case of a heuristically committed transaction,
- * this method should not be invoked at the end of the second phase of the
- * two-phase commit protocol. Instead, the <code>handleTxCompletion</code>
- * call should be postponed until the heuristic outcome is forgotten.
- *
- * @param localTransactionId the local id of the completed transaction.
- */
- void handleTxCompletion(long localTransactionId);
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/recovery/XAResourceAccess.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/recovery/XAResourceAccess.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/recovery/XAResourceAccess.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,40 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.recovery;
-
-/**
- * Interface with a single method for releasing the access to an
- * <code>XAResource</code>. The holder of an <code>XAResourceAccess<code>
- * instance has access to some <code>XAResource</code> through a connection
- * to an XA datasource. When it finishes using the <code>XAResource</code>,
- * it must call <code>release</code> on the <code>XAResourceAccess<code>
- * instance. If no other object has access to the <code>XAResource</code>,
- * then the <code>relase</code> call closes the underlying
- * <code>XAConnection</code>.
- *
- * @author <a href="reverbel at ime.usp.br">Francisco Reverbel</a>
- * @version $Revision$
- */
-public interface XAResourceAccess
-{
- void release();
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/recovery/XAWork.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/recovery/XAWork.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/recovery/XAWork.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,64 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.recovery;
-
-import javax.transaction.xa.XAResource;
-import javax.transaction.xa.Xid;
-
-/**
- * "Struct class" that represents the work to be performed by a given XA
- * resource for a given transaction branch.
- *
- * @author <a href="mailto:reverbel at ime.usp.br">Francisco Reverbel</a>
- * @version $Revision$
- */
-public class XAWork
-{
- /** The XAResource. */
- public XAResource res;
-
- /** The transaction branch identifier. */
- public Xid xid;
-
- /** The XAResourceAccess to be released when the work is completed. */
- public XAResourceAccess xaResourceAccess;
-
- /**
- * Constructs an <code>XAWork</code> instance given an
- * <code>XAResource</code>, a transaction branch identifier, and
- * an <code>XAResourceAccess</code> instance.
- *
- * @param res the <code>XAResource</code>
- * @param xid the transaction branch identifier.
- * @param xaResourceAccess the <code>XAResourceAccess</code> instance
- * to be released when the work is completed.
- */
- XAWork(XAResource res,
- Xid xid,
- RecoveryManager.XAResourceAccessImpl xaResourceAccess)
- {
- this.res = res;
- this.xid = xid;
- this.xaResourceAccess = xaResourceAccess.duplicate();
- }
-
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/recovery/XidFactoryInitializationService.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/recovery/XidFactoryInitializationService.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/recovery/XidFactoryInitializationService.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,166 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.recovery;
-
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.nio.ByteBuffer;
-import java.util.zip.Adler32;
-import java.util.zip.Checksum;
-
-import javax.management.ObjectName;
-
-import org.jboss.system.ServiceMBeanSupport;
-import org.jboss.tm.LocalId;
-import org.jboss.tm.XidFactoryMBean;
-
-/**
- * MBean service that distinguishes "transaction generations", which correspond
- * to different executions of a JBoss server, by stuffing a "transaction
- * generation number" into the high part of all the local transaction ids
- * created by an execution of the server. This service keeps the next
- * transaction generation number (the value that the next server run will stuff
- * into the high part of its local transaction ids) in a file, which it reads
- * and updates at server startup time.
- *
- * @author <a href="mailto:reverbel at ime.usp.br">Francisco Reverbel</a>
- * @version $Revision$
- */
-public class XidFactoryInitializationService
- extends ServiceMBeanSupport
- implements XidFactoryInitializationServiceMBean
-{
- private ObjectName xidFactory;
- private String filename;
- private int nextTxGenerationNumber = 0;
-
- // ServiceMBeanSupport override ----------------------------------
-
- /**
- * @see org.jboss.system.ServiceMBeanSupport#startService()
- */
- protected void startService()
- throws Exception
- {
- super.startService();
- XidFactoryMBean xidFactoryObj =
- (XidFactoryMBean) getServer().getAttribute(xidFactory, "Instance");
-
- File nextTxGenerationFile = new File(filename);
- nextTxGenerationFile = nextTxGenerationFile.getAbsoluteFile();
- if (!nextTxGenerationFile.createNewFile())
- {
- // Read existing file.
- InputStream in = new FileInputStream(nextTxGenerationFile);
- DataInputStream dataIn = new DataInputStream(in);
- int txGenNumberFromFile = dataIn.readInt();
- int checksumFromFile = dataIn.readInt();
- dataIn.close();
-
- // Verify the checksum.
- ByteBuffer buffer = ByteBuffer.allocate(4);
- buffer.putInt(txGenNumberFromFile);
- Checksum checksum = new Adler32();
- checksum.update(buffer.array(), 0, 4);
- if ((int) checksum.getValue() != checksumFromFile)
- throw new RuntimeException("Incorrect checksum in file " +
- nextTxGenerationFile + ". Could not " +
- "obtain the next transaction " +
- "generation number.");
-
- // Rename existing file
- File backupFile = new File(filename + ".bak");
- backupFile.delete();
- nextTxGenerationFile.renameTo(backupFile);
- nextTxGenerationNumber = txGenNumberFromFile;
- }
-
- // Set the transaction generation in the Xid factory.
- xidFactoryObj.setGlobalIdNumber(LocalId.assemble(nextTxGenerationNumber,
- 0 /* tx number */));
-
- // Increment and save the next transaction generation number.
- nextTxGenerationNumber++;
- ByteBuffer buffer = ByteBuffer.allocate(4);
- buffer.putInt(nextTxGenerationNumber);
- Checksum checksum = new Adler32();
- checksum.update(buffer.array(), 0, 4);
-
- FileOutputStream out= new FileOutputStream(nextTxGenerationFile);
- DataOutputStream dataOut = new DataOutputStream(out);
- dataOut.writeInt(nextTxGenerationNumber);
- dataOut.writeInt((int) checksum.getValue());
- dataOut.flush();
- out.getFD().sync();
- dataOut.close();
- }
-
- // XidFactoryInitializationServiceMBean implementation -----------
-
- /**
- * @see org.jboss.tm.recovery.XidFactoryInitializationServiceMBean#getXidFactory()
- */
- public ObjectName getXidFactory()
- {
- return xidFactory;
- }
-
- /**
- * @see org.jboss.tm.recovery.XidFactoryInitializationServiceMBean#setXidFactory(
- * javax.management.ObjectName)
- */
- public void setXidFactory(ObjectName xidFactory)
- {
- this.xidFactory = xidFactory;
- }
-
- /**
- * @see org.jboss.tm.recovery.XidFactoryInitializationServiceMBean#getNextTxGenerationFile()
- */
- public String getNextTxGenerationFile()
- {
- return filename;
- }
-
- /**
- * @see org.jboss.tm.recovery.XidFactoryInitializationServiceMBean#setNextTxGenerationFile(
- * java.lang.String)
- */
- public void setNextTxGenerationFile(String filename)
- {
- this.filename = filename;
- }
-
- /**
- * @see org.jboss.tm.recovery.XidFactoryInitializationServiceMBean#getNextTxGenerationNumber()
- */
- public int getNextTxGenerationNumber()
- {
- return nextTxGenerationNumber;
- }
-
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/recovery/XidFactoryInitializationServiceMBean.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/recovery/XidFactoryInitializationServiceMBean.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/recovery/XidFactoryInitializationServiceMBean.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,53 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.recovery;
-
-import javax.management.ObjectName;
-
-import org.jboss.system.ServiceMBean;
-
-/**
- * MBean interface of a service that distinguishes "transaction generations",
- * which correspond to different executions of a JBoss server, by stuffing
- * a "transaction generation number" into the high part of all the local
- * transaction ids created by an execution of the server. This service keeps
- * the next transaction generation number (the value that the next server run
- * will stuff into the high part of its local transaction ids) in a file, which
- * it reads and updates at server startup time.
- *
- * @author <a href="mailto:reverbel at ime.usp.br">Francisco Reverbel</a>
- * @version $Revision$
- */
-public interface XidFactoryInitializationServiceMBean
- extends ServiceMBean
-{
- ObjectName getXidFactory();
-
- void setXidFactory(ObjectName xidFactory);
-
- String getNextTxGenerationFile();
-
- void setNextTxGenerationFile(String filename);
-
- int getNextTxGenerationNumber();
-
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/recovery/test/TestForceTime.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/recovery/test/TestForceTime.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/recovery/test/TestForceTime.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,299 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.recovery.test;
-
-import org.jboss.tm.recovery.BatchRecoveryLogger;
-import org.jboss.tm.recovery.BatchWriter;
-import org.jboss.tm.recovery.RecoveryLogTerminator;
-import org.jboss.tm.XidFactory;
-
-import java.io.RandomAccessFile;
-import java.io.IOException;
-import java.io.File;
-import java.nio.channels.FileChannel;
-import java.nio.ByteBuffer;
-
-import EDU.oswego.cs.dl.util.concurrent.Latch;
-
-import javax.transaction.xa.Xid;
-
-/**
- * benches file per thread vs. batch queue
- *
- * @author <a href="mailto:bill at jboss.org">Bill Burke</a>
- * @version $Revision$
- */
-public class TestForceTime
-{
- private static final int RECORD_SIZE = Xid.MAXGTRIDSIZE * 2;
- private static int NUM_DIRS = 2;
- private static final int ITERATIONS = 100;
- private static int numThreads = 500;
- private static long average;
- private static int count;
- private static long startTime;
- private static XidFactory factory = new XidFactory();
- private static int tx_per_sec;
-
-
- private static class BatchThread implements Runnable
- {
- private BatchRecoveryLogger logger;
- private int id;
-
- public BatchThread(int id, BatchRecoveryLogger logger)
- {
- this.logger = logger;
- this.id = id;
- }
-
- public void run()
- {
- synchronized (startLock)
- {
- try
- {
- startLock.wait();
- }
- catch (InterruptedException e)
- {
- throw new RuntimeException(e);
- }
- }
-
- try
- {
- //System.out.println("Starting " + id);
-
- long start = System.currentTimeMillis();
- for (int i = 0; i < ITERATIONS; i++)
- {
- Xid xid = factory.newXid();
- RecoveryLogTerminator term = logger.committing(xid);
- term.committed(xid);
- }
- long time = System.currentTimeMillis() - start;
- //System.out.println(ITERATIONS + " batches took : " + time + " of id " + id);
- stats("batch: ", time);
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
- }
-
- }
-
- private static void stats(String tag, long time)
- {
- synchronized (startLock)
- {
- count++;
- if (count == numThreads)
- {
- long end = System.currentTimeMillis() - startTime;
- System.out.println(tag + " TOTAL TIME TOOK: " + end);
- tx_per_sec = (int) (((double) (numThreads * ITERATIONS) / (double) end) * 1000);
- System.out.println("tx per sec = " + tx_per_sec);
- double avg = (double) average / (double) numThreads;
- //System.out.println(tag + "average time took: " + avg);
- }
- average += time;
- }
- }
-
- public static void main(String[] args) throws Exception
- {
-
-
- for (int i = 1; i <= 1024; i = i * 2)
- {
- System.out.println("*** threads: " + i);
- NUM_DIRS = 1;
- numThreads = i;
- average = 0;
- count = 0;
- runLogger();
- }
-
-
- /*
- int i = 1024;
- int last_tx = 0;
- while (true)
- {
- System.out.println("*** threads: " + i);
- NUM_DIRS = 1;
- numThreads = i;
- average = 0;
- count = 0;
- runLogger();
- if (last_tx > tx_per_sec) break;
- last_tx = tx_per_sec;
- i+= 1;
- }
- */
- }
-
- private static void runLogger()
- throws IOException, InterruptedException
- {
- average = 0;
- File dir = new File("/tmp/batchRecovery");
- dir.mkdirs();
- String[] dirs = new String[NUM_DIRS];
- for (int i = 0; i < dirs.length; i++)
- {
- dirs[i] = "/tmp/batchRecovery/dir" + i;
- }
- BatchRecoveryLogger logger = new BatchRecoveryLogger();
- logger.setDirectoryList(dirs);
- logger.setMaxLogSize(ITERATIONS * numThreads);
- try
- {
- logger.start();
- }
- catch (Exception e)
- {
- throw new RuntimeException(e);
- }
-
- Thread[] workers = new Thread[numThreads];
-
- for (int i = 0; i < numThreads; i++)
- {
- workers[i] = new Thread(new BatchThread(i, logger));
- workers[i].start();
- }
-
- Thread.sleep(1000);
-
- //System.out.println("waking up threads");
- count = 0;
- startTime = System.currentTimeMillis();
-
- synchronized (startLock)
- {
- startLock.notifyAll();
- }
-
- for (int i = 0; i < numThreads; i++)
- {
- workers[i].join();
- }
-
- //System.out.println("logger.stop");
- try
- {
- logger.stop();
- }
- catch (Exception e)
- {
- throw new RuntimeException(e);
- }
- }
-
- private static void simple()
- throws Exception
- {
- average = 0;
- Thread[] workers = new Thread[numThreads];
-
- for (int i = 0; i < numThreads; i++)
- {
- workers[i] = new Thread(new SimpleThread(i));
- workers[i].start();
- }
-
- Thread.sleep(1000);
-
- //System.out.println("waking up threads");
-
- startTime = System.currentTimeMillis();
- count = 0;
-
- synchronized (startLock)
- {
- startLock.notifyAll();
- }
-
- for (int i = 0; i < numThreads; i++)
- {
- workers[i].join();
- }
- }
-
- private static Object startLock = new Object();
-
- private static class SimpleThread implements Runnable
- {
- private FileChannel channel;
- private RandomAccessFile raf;
- private int id;
- private BatchWriter logger;
-
- public SimpleThread(int id) throws IOException
- {
-
- File dir = new File("/tmp/SimpleRecovery/dir" + id);
- dir.mkdirs();
- logger = new BatchWriter("hello", 100, dir, RECORD_SIZE, ITERATIONS * numThreads);
- }
-
- public void run()
- {
- synchronized (startLock)
- {
- try
- {
- startLock.wait();
- }
- catch (InterruptedException e)
- {
- throw new RuntimeException(e);
- }
- }
-
- //System.out.println("Starting...");
-
- long start = System.currentTimeMillis();
- boolean failed = false;
- for (int i = 0; i < ITERATIONS; i++)
- {
- byte[] bytes = new byte[RECORD_SIZE];
- ByteBuffer buf = ByteBuffer.wrap(bytes);
- try
- {
- logger.committing(buf);
- }
- catch (Exception e)
- {
- failed = true;
- }
- }
- long time = (System.currentTimeMillis() - start);
- //System.out.println(ITERATIONS + " forces took: " + time);
- stats("SIMPLE: " + failed + " ", time);
- logger.cleanup();
- }
- }
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/recovery/test/TestOracleXA.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/recovery/test/TestOracleXA.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/recovery/test/TestOracleXA.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,480 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.recovery.test;
-
-import java.sql.*;
-import javax.sql.*;
-
-import oracle.jdbc.*;
-import oracle.jdbc.pool.*;
-import oracle.jdbc.xa.OracleXid;
-import oracle.jdbc.xa.OracleXAException;
-import oracle.jdbc.xa.client.*;
-
-import javax.transaction.xa.*;
-
-import org.jboss.tm.XidFactory;
-import org.jboss.tm.XidImpl;
-
-
-/**
- * Comment
- *
- * @author <a href="mailto:bill at jboss.org">Bill Burke</a>
- * @version $Revision$
- */
-public class TestOracleXA
-{
-
- static String URL1 = "jdbc:oracle:thin:@192.168.1.102:1521:joracle";
- static String URL2 = "jdbc:oracle:thin:@192.168.1.102:1521:joracle";
-
-
- public static void main(String args [])
- {
- try
- {
- boolean fail = false;
-
-
- if (factory == null)
- {
- factory = new XidFactory();
- factory.setPad(true);
- base = (XidImpl) factory.newXid();
- }
-
- if (args.length > 0)
- {
-
- if (args[0].equals("recover"))
- {
- recover2();
- return;
- }
- else if (args[0].equals("print"))
- {
- DriverManager.registerDriver(new OracleDriver());
- printResults();
- return;
- }
- else if (args[0].equals("fail"))
- {
- fail = true;
- }
- else if (args[0].equals("nonxa"))
- {
- DriverManager.registerDriver(new OracleDriver());
- nonXA();
- return;
- }
- }
-
-
- DriverManager.registerDriver(new OracleDriver());
-
- // You can put a database name after the @ sign in the connection URL.
- Connection conna =
- DriverManager.getConnection(URL1, "HR", "H19");
-
- Connection connb =
- DriverManager.getConnection(URL2, "HR", "H19");
-
- // Prepare a statement to create the table
- Statement stmta = conna.createStatement();
-
- // Prepare a statement to create the table
- Statement stmtb = connb.createStatement();
-
- try
- {
- // Drop the test table
- stmta.execute("drop table my_table");
- }
- catch (SQLException e)
- {
- System.out.println("error");
- }
-
- try
- {
- // Create a test table
- stmta.execute("create table my_table (col1 int)");
- }
- catch (SQLException e)
- {
- System.out.println("error");
- }
-
- try
- {
- // Drop the test table
- stmtb.execute("drop table my_tab");
- }
- catch (SQLException e)
- {
- System.out.println("error");
- }
-
- try
- {
- // Create a test table
- stmtb.execute("create table my_tab (col1 char(30))");
- }
- catch (SQLException e)
- {
- System.out.println("error");
- }
-
- stmta.close();
- stmta = null;
- stmtb.close();
- stmtb = null;
-
- conna.commit();
- conna.close();
- conna = null;
- connb.commit();
- connb.close();
- connb = null;
-
-
-
- // Create XADataSource instances and set properties.
- OracleXADataSource oxds1 = new OracleXADataSource();
- oxds1.setURL(URL1);
- oxds1.setUser("HR");
- oxds1.setPassword("H19");
-
- OracleXADataSource oxds2 = new OracleXADataSource();
-
- oxds2.setURL(URL2);
- oxds2.setUser("HR");
- oxds2.setPassword("H19");
-
- // Get XA connections to the underlying data sources
- XAConnection pc1 = oxds1.getXAConnection();
- XAConnection pc2 = oxds2.getXAConnection();
-
- // Get the physical connections
- Connection conn1 = pc1.getConnection();
- Connection conn2 = pc2.getConnection();
-
- // Get the XA resources
- XAResource oxar1 = pc1.getXAResource();
- XAResource oxar2 = pc2.getXAResource();
-
- // Create the Xids With the Same Global Ids
- Xid xid1 = createXid(1);
- Xid xid2 = createXid(2);
-
- // Start the Resources
- oxar1.start(xid1, XAResource.TMNOFLAGS);
- oxar2.start(xid2, XAResource.TMNOFLAGS);
-
- // Execute SQL operations with conn1 and conn2
- doSomeWork1(conn1);
- doSomeWork2(conn2);
-
- // END both the branches -- IMPORTANT
- oxar1.end(xid1, XAResource.TMSUCCESS);
- oxar2.end(xid2, XAResource.TMSUCCESS);
-
- // Prepare the RMs
- int prp1 = oxar1.prepare(xid1);
- int prp2 = oxar2.prepare(xid2);
-
- System.out.println("Return value of prepare 1 is " + prp1);
- System.out.println("Return value of prepare 2 is " + prp2);
-
- boolean do_commit = true;
-
- if (!((prp1 == XAResource.XA_OK) || (prp1 == XAResource.XA_RDONLY)))
- do_commit = false;
-
- if (!((prp2 == XAResource.XA_OK) || (prp2 == XAResource.XA_RDONLY)))
- do_commit = false;
-
- System.out.println("do_commit is " + do_commit);
- System.out.println("Is oxar1 same as oxar2 ? " + oxar1.isSameRM(oxar2));
-
-
- if (fail)
- {
- System.exit(1);
- // Close connections
- conn1.close();
- conn1 = null;
- conn2.close();
- conn2 = null;
-
- pc1.close();
- pc1 = null;
- pc2.close();
- pc2 = null;
-
- recover2();
- }
-
- else
- {
-
- if (prp1 == XAResource.XA_OK)
- if (do_commit)
- oxar1.commit(xid1, false);
- else
- oxar1.rollback(xid1);
-
- if (prp2 == XAResource.XA_OK)
- if (do_commit)
- oxar2.commit(xid2, false);
- else
- oxar2.rollback(xid2);
-
- // Close connections
- conn1.close();
- conn1 = null;
- conn2.close();
- conn2 = null;
-
- pc1.close();
- pc1 = null;
- pc2.close();
- pc2 = null;
- }
-
-
- printResults();
-
- }
- catch (SQLException sqe)
- {
- sqe.printStackTrace();
- }
- catch (XAException xae)
- {
- if (xae instanceof OracleXAException)
- {
- System.out.println("XA Error is " +
- ((OracleXAException) xae).getXAError());
- System.out.println("SQL Error is " +
- ((OracleXAException) xae).getOracleError());
- }
- else
- {
- xae.printStackTrace();
- System.out.println("error code: " + xae.errorCode);
- }
- }
- catch (Throwable t)
- {
- System.out.println("****SHIT!!!");
- t.printStackTrace();
- }
- System.out.println("DONE!!!");
- }
-
- private static void recover2()
- throws SQLException, XAException
- {
- // Create XADataSource instances and set properties.
- OracleXADataSource oxds1 = new OracleXADataSource();
- oxds1.setURL(URL1);
- oxds1.setUser("HR");
- oxds1.setPassword("H19");
-
- OracleXADataSource oxds2 = new OracleXADataSource();
-
- oxds2.setURL(URL2);
- oxds2.setUser("HR");
- oxds2.setPassword("H19");
-
- XAConnection pc1;
- XAConnection pc2;
- Connection conn1;
- Connection conn2;
- XAResource oxar1;
- XAResource oxar2;
- // TRY RECOVERING
-
- // Get XA connections to the underlying data sources
- pc1 = oxds1.getXAConnection();
- pc2 = oxds2.getXAConnection();
-
- // Get the physical connections
- conn1 = pc1.getConnection();
- conn2 = pc2.getConnection();
-
- // Get the XA resources
- oxar1 = pc1.getXAResource();
- oxar2 = pc2.getXAResource();
-
- System.out.println("*** TRYING TO RECOVER");
-
- Xid[] recover1 = oxar1.recover(XAResource.TMSTARTRSCAN | XAResource.TMENDRSCAN);
- if (recover1 != null)
- {
- System.out.println("RECOVERING 1");
- for (int i = 0; i < recover1.length; i++)
- {
- Xid xid = factory.fromXid(recover1[i]);
- System.out.println("recovering XID: " + xid);
- oxar1.commit(recover1[i], false);
- }
- }
- else
- {
- System.out.println("RECOVER1 returned null");
- }
-
- Xid[] recover2 = oxar2.recover(XAResource.TMSTARTRSCAN | XAResource.TMENDRSCAN);
- if (recover2 != null)
- {
- System.out.println("RECOVERING 2");
- for (int i = 0; i < recover2.length; i++)
- {
- Xid xid = factory.fromXid(recover2[i]);
- System.out.println("recovering XID: " + xid);
- oxar2.commit(recover2[i], false);
- }
- }
- else
- {
- System.out.println("RECOVER1 returned null");
- }
-
- System.out.println("HERE!!!!!");
-
- // Close connections
- conn1.close();
- conn1 = null;
- conn2.close();
- conn2 = null;
-
- pc1.close();
- pc1 = null;
- pc2.close();
- pc2 = null;
- }
-
- private static void printResults()
- throws SQLException
- {
- Connection conna;
- Connection connb;
- Statement stmta;
- Statement stmtb;
- conna =
- DriverManager.getConnection(URL1, "HR", "H19");
-
- connb =
- DriverManager.getConnection(URL2, "HR", "H19");
-
- // Prepare a statement to create the table
- stmta = conna.createStatement();
-
- // Prepare a statement to create the table
- stmtb = connb.createStatement();
-
- ResultSet rset = stmta.executeQuery("select col1 from my_table");
- while (rset.next())
- System.out.println("Col1 is " + rset.getInt(1));
-
- rset.close();
- rset = null;
-
- rset = stmtb.executeQuery("select col1 from my_tab");
- while (rset.next())
- System.out.println("Col1 is " + rset.getString(1));
-
- rset.close();
- rset = null;
-
- stmta.close();
- stmta = null;
- stmtb.close();
- stmtb = null;
-
- conna.commit();
- conna.close();
- conna = null;
- connb.commit();
- connb.close();
- connb = null;
- }
-
- private static void nonXA()
- throws SQLException
- {
- Connection conna;
- Connection connb;
- Statement stmta;
- Statement stmtb;
- conna =
- DriverManager.getConnection(URL1, "HR", "H19");
- conna.setAutoCommit(false);
-
- connb =
- DriverManager.getConnection(URL2, "HR", "H19");
-
- connb.setAutoCommit(false);
-
- doSomeWork1(conna);
- doSomeWork2(connb);
-
- System.exit(1);
-
- conna.commit();
- conna.close();
- conna = null;
- connb.commit();
- connb.close();
- connb = null;
- }
-
- static XidFactory factory;
- static XidImpl base;
-
- static Xid createXid(int bids)
- throws XAException
- {
- return factory.newBranch(base, bids);
- }
-
- private static void doSomeWork1(Connection conn)
- throws SQLException
- {
- Statement st = conn.createStatement();
- st.executeUpdate("insert into my_table values(1)");
- st.close();
- }
-
- private static void doSomeWork2(Connection conn)
- throws SQLException
- {
- Statement st = conn.createStatement();
- st.executeUpdate("insert into my_tab values('world')");
- st.close();
- }
-
-
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/remoting/ClientInvocationHandler.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/remoting/ClientInvocationHandler.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/remoting/ClientInvocationHandler.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,372 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.remoting;
-
-import java.io.Externalizable;
-import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
-import java.rmi.RemoteException;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.jboss.remoting.CannotConnectException;
-import org.jboss.remoting.Client;
-import org.jboss.remoting.InvalidConfigurationException;
-import org.jboss.remoting.InvokerLocator;
-import org.jboss.tm.remoting.interfaces.Coordinator;
-import org.jboss.tm.remoting.interfaces.RecoveryCoordinator;
-import org.jboss.tm.remoting.interfaces.Resource;
-import org.jboss.tm.remoting.interfaces.Synchronization;
-import org.jboss.tm.remoting.interfaces.Terminator;
-import org.jboss.tm.remoting.interfaces.TransactionFactory;
-import org.jboss.tm.remoting.server.DistributedTransactionManager;
-
-/**
- * Client-side DTM stubs are dynamic proxies that use this
- * <code>InvocationHandler</code> implementation.
- *
- * @author <a href="mailto:reverbel at ime.usp.br">Francisco Reverbel</a>
- * @version $Revision$
- */
-public class ClientInvocationHandler
- implements InvocationHandler, Externalizable
-{
- static final long serialVersionUID = 2253923354553253502L;
-
- // Constants (DTM interface codes) -------------------------------
-
- public static final char TRANSACTION_FACTORY = 'F';
- public static final char COORDINATOR = 'C';
- public static final char TERMINATOR = 'T';
- public static final char RESOURCE = 'R';
- public static final char RECOVERY_COORDINATOR = 'V';
- public static final char SYNCHRONIZATION = 'S';
-
- // Fields --------------------------------------------------------
-
- private char interfaceCode;
- private long targetObjectId;
- private InvokerLocator[] locators;
- private Client client; // lazily initialized by the invoke method
- private String stringRepresentation;
-
- // Constructors --------------------------------------------------
-
- /** No-arg constructor for externalization. */
- public ClientInvocationHandler()
- {
- }
-
- /**
- * Constructs a <code>ClientInvocationHandler</code> for a target object
- * whose id is 0, given the remote interface of the target and its
- * <code>InvokerLocator</code>s.
- */
- public ClientInvocationHandler(Class interf, InvokerLocator[] locators)
- throws Exception
- {
- this(interf, 0, locators);
- }
-
- /**
- * Constructs a <code>ClientInvocationHandler</code> for a target object
- * given the remote interface of the target, its object id, and its
- * <code>InvokerLocator</code>s.
- */
- public ClientInvocationHandler(Class interf,
- long targetObjectId,
- InvokerLocator[] locators)
- throws Exception
- {
- this(getInterfaceCode(interf), targetObjectId, locators);
- }
-
- /**
- * Constructs a <code>ClientInvocationHandler</code> for a target object
- * whose id is 0, given the remote interface code of the target and its
- * <code>InvokerLocator</code>s.
- */
- public ClientInvocationHandler(char interfaceCode, InvokerLocator[] locators)
- throws Exception
- {
- this(interfaceCode, 0, locators);
- }
-
- /**
- * Constructs a <code>ClientInvocationHandler</code> for a target object
- * given the remote interface code of the target, its object id, and its
- * <code>InvokerLocator</code>s.
- */
- public ClientInvocationHandler(char interfaceCode,
- long targetObjectId,
- InvokerLocator[] locators)
- throws Exception
- {
- if (interfaceCode != TRANSACTION_FACTORY
- && interfaceCode != COORDINATOR
- && interfaceCode != TERMINATOR
- && interfaceCode != RESOURCE
- && interfaceCode != RECOVERY_COORDINATOR
- && interfaceCode != SYNCHRONIZATION)
- throw new IllegalArgumentException();
-
- if (locators.length == 0)
- throw new IllegalArgumentException();
-
- this.interfaceCode = interfaceCode;
- this.targetObjectId = targetObjectId;
- this.locators = locators;
- }
-
- // Utility methods -----------------------------------------------
-
- /**
- * Returns a <code>Class</code> instance representing the remote interface
- * implemented by the dynamic proxies that use this invocation handler.
- */
- Class getClientInterface() // called by RemoteInterface.toString
- {
- switch (interfaceCode)
- {
- case TRANSACTION_FACTORY:
- return TransactionFactory.class;
- case COORDINATOR:
- return Coordinator.class;
- case TERMINATOR:
- return Terminator.class;
- case RESOURCE:
- return Resource.class;
- case RECOVERY_COORDINATOR:
- return RecoveryCoordinator.class;
- case SYNCHRONIZATION:
- return Synchronization.class;
- }
- throw new RuntimeException("Illegal value in field interfaceCode");
- }
-
- /**
- * Takes a <code>Class</code> instance representing a DTM interface
- * and converts is into an interface code.
- */
- private static char getInterfaceCode(Class interf)
- {
- if (interf == TransactionFactory.class)
- return TRANSACTION_FACTORY;
- else if (interf == Coordinator.class)
- return COORDINATOR;
- else if (interf == Terminator.class)
- return TERMINATOR;
- else if (interf == Resource.class)
- return RESOURCE;
- else if (interf == RecoveryCoordinator.class)
- return RECOVERY_COORDINATOR;
- else if (interf == Synchronization.class)
- return SYNCHRONIZATION;
- else
- throw new IllegalArgumentException("argument is not a DTM interface");
- }
-
- // InvocationHandler method --------------------------------------
-
- /**
- * Uses the <code>InvokerLocator</code> associated with this handler to
- * send out an <code>Invocation</code> containing this handler's target
- * object id, the given method, and the given arguments.
- */
- public Object invoke(Object proxy, Method method, Object[] args)
- throws Throwable
- {
- Exception savedException = null;
-
- if (method.getDeclaringClass() == Object.class)
- {
- String methodName = method.getName();
-
- if (methodName.equals("toString"))
- return this.toString();
- else if (methodName.equals("hashCode"))
- return new Integer(this.toString().hashCode());
- else if (methodName.equals("equals"))
- return new Boolean(this.toString().equals(args[0].toString()));
- }
-
- if (client != null)
- {
- // Non-null client: just use it!
- try
- {
- return client.invoke(new Invocation(targetObjectId, method, args));
- }
- catch (CannotConnectException e)
- {
- client = null;
- }
-
- }
-
- // Either client has not been initialized yet or it became null after
- // a failed invocation attempt. Try each locator in sequence. If all
- // of them fail, propagate the last exception up to the caller, wrapped
- // into a RemoteException.
- Invocation invocation = new Invocation(targetObjectId, method, args);
- for (int i = 0; i < locators.length; i++)
- {
- try
- {
- client = new Client(locators[i],
- DistributedTransactionManager.SUBSYSTEM);
- return client.invoke(invocation);
- }
- catch (CannotConnectException e)
- {
- client = null;
- savedException = e;
- }
- catch (InvalidConfigurationException e)
- {
- client = null;
- savedException = e;
- }
- }
- throw new RemoteException(savedException.getClass().getName(),
- savedException);
- }
-
- // Externalizable methods ----------------------------------------
-
- /**
- * Reads a <code>ClientInvocationHandler</code> in externalized form:
- * interface code, target object id, and locator URI.
- */
- public void readExternal(ObjectInput in)
- throws IOException, ClassNotFoundException
- {
- this.interfaceCode = in.readChar();
- this.targetObjectId = in.readLong();
- short len = in.readShort();
- if (len < 1)
- throw new IOException("ObjectInput does not contain a valid " +
- "ClientInvocationHandler");
- this.locators = new InvokerLocator[len];
- for (int i = 0; i < len; i++)
- {
- this.locators[i] = new InvokerLocator(in.readUTF());
- }
- this.client = null;
- }
-
- /**
- * Writes a <code>ClientInvocationHandler</code> in externalized form:
- * interface code, target object id, and locator URI.
- */
- public void writeExternal(ObjectOutput out) throws IOException
- {
- out.writeChar(interfaceCode);
- out.writeLong(targetObjectId);
- out.writeShort(locators.length);
- for (int i = 0; i < locators.length; i++)
- {
- out.writeUTF(locators[i].getLocatorURI());
- }
- }
-
- // Conversion to/from string representation
-
- /**
- * Converts a <code>ClientInvocationHandler</code> to string. These are
- * examples of stringfied handlers:
- * <p>
- * <code>T3d00000004c75,socket://server4.acme.com:3873/</code><br>
- * <code>C1b6,socket://zee.acme.com:3873/|rmi://zee.acme.com:5678/</code>
- * <p>
- * The handler comprises an interface code (the first character),
- * immediately followed by the hexadecimal representation of the target
- * object id (a long value), a comma (','), and a list of locator URIs
- * separated by vertical bars ('|'s).
- */
- public String toString()
- {
- if (stringRepresentation == null)
- stringRepresentation = interfaceCode +
- Long.toHexString(targetObjectId) +
- ',' + locators[0].getLocatorURI();
- for (int i = 1; i < locators.length; i++)
- {
- stringRepresentation += '|' + locators[i].getLocatorURI();
- }
- return stringRepresentation;
- }
-
- /**
- * Converts a stringfied handler back into a
- * <code>ClientInvocationHandler</code> instance.
- */
- public static ClientInvocationHandler fromString(String s)
- throws Exception
- {
- String locatorURI;
- InvokerLocator locator;
-
- int oidEndIndex = s.indexOf(',');
- if (oidEndIndex == -1)
- throw new IllegalArgumentException();
-
- String oidString = s.substring(1, oidEndIndex);
- int uriStartIndex = oidEndIndex + 1;
- int uriEndIndex = s.indexOf('|', uriStartIndex);
-
- if (uriEndIndex == -1)
- {
- // single URI
- locatorURI = s.substring(uriStartIndex);
- locator = new InvokerLocator(locatorURI);
- return new ClientInvocationHandler(s.charAt(0),
- Long.parseLong(oidString, 16),
- new InvokerLocator[] { locator });
- }
- else
- {
- // multiple URIs separated by '|'s
- List locatorList = new ArrayList();
- while (uriEndIndex != -1)
- {
- locatorURI = s.substring(uriStartIndex, uriEndIndex);
- locator = new InvokerLocator(locatorURI);
- locatorList.add(locator);
- uriStartIndex = uriEndIndex + 1;
- uriEndIndex = s.indexOf('|', uriStartIndex);
- }
- locatorURI = s.substring(uriStartIndex);
- locator = new InvokerLocator(locatorURI);
- locatorList.add(locator);
- InvokerLocator[] locators =
- (InvokerLocator[]) locatorList.toArray(new InvokerLocator[0]);
- return new ClientInvocationHandler(s.charAt(0),
- Long.parseLong(oidString, 16),
- locators);
- }
- }
-
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/remoting/Invocation.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/remoting/Invocation.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/remoting/Invocation.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,671 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.remoting;
-
-import java.io.Serializable;
-import java.lang.reflect.Method;
-import java.rmi.RemoteException;
-
-import javax.transaction.HeuristicCommitException;
-import javax.transaction.HeuristicMixedException;
-import javax.transaction.HeuristicRollbackException;
-
-import org.jboss.remoting.InvokerLocator;
-import org.jboss.tm.GlobalId;
-import org.jboss.tm.remoting.interfaces.Coordinator;
-import org.jboss.tm.remoting.interfaces.HeuristicHazardException;
-import org.jboss.tm.remoting.interfaces.RecoveryCoordinator;
-import org.jboss.tm.remoting.interfaces.Resource;
-import org.jboss.tm.remoting.interfaces.Status;
-import org.jboss.tm.remoting.interfaces.Synchronization;
-import org.jboss.tm.remoting.interfaces.Terminator;
-import org.jboss.tm.remoting.interfaces.TxPropagationContext;
-import org.jboss.tm.remoting.interfaces.TransactionFactory;
-import org.jboss.tm.remoting.interfaces.TransactionInactiveException;
-import org.jboss.tm.remoting.interfaces.TransactionNotPreparedException;
-import org.jboss.tm.remoting.interfaces.Vote;
-
-
-/**
- * An instance of this class represents a method invocation on any of the
- * remote interfaces of the transaction service, which are the interfaces
- * defined in the package <code>org.jboss.tm.remoting.interfaces<code>.
- *
- * @author <a href="mailto:reverbel at ime.usp.br">Francisco Reverbel</a>
- * @version $Revision$
- */
-public class Invocation
- implements Serializable
-{
- static final long serialVersionUID = -7256134284357215230L;
-
- // Nested interfaces ---------------------------------------------
-
- /**
- * Interface of an auxiliary object that knows how to perform an invocation
- * to a particular method. All the nested interfaces which follow have an
- * Invoker-valued static final field for each method of the corresponding
- * transaction service interface. For example, the nested interface
- * <code>ITransactionFactory</code> (see below) corresponds to the interface
- * <code>org.jboss.tm.remoting.interfaces.TransactionFactory</code>. It has
- * an Invoker-valued field <code>CREATE</code> and a method
- * <code>create</code>, which mirrors the similarly named method in
- * <code>org.jboss.tm.remoting.interface.TransactionFactory</code>.
- *
- * The nested interfaces below should be implemented by one or more servant
- * objects associated with the <code>ServerInvocationHandler</code>. Note
- * that all the "mirror methods" in those interfaces take an additional
- * parameter <code>targetId</code>, which allows a single servant to
- * incarnate multiple target objects. At each invocation, that parameter
- * identifies the target object for that invocation.
- */
- private static interface Invoker
- {
- Object invoke(Object servant, long targetId, Object[] args)
- throws Throwable;
- }
-
- /**
- * This interface mirrors the interface <code>TransactionFactory</code> in
- * <code>org.jboss.tm.remoting.interfaces</code>. Attention: method id
- * constants (<code>M_</code>* fields) are indices to an invoker array,
- * so they must be consecutive integers in the range 0..max_index. They also
- * must be unique among all mirror interfaces.
- */
- public static interface ITransactionFactory
- {
- /** Method id for TransactionFactory.create */
- static final int M_CREATE = 0;
-
- /** Method id for TransactionFactory.recreate */
- static final int M_RECREATE = 1;
-
- /** Invoker for TransactionFactory.create */
- static final Invoker CREATE = new Invoker()
- {
- public Object invoke(Object servant, long targetId, Object[] args)
- throws Throwable
- {
- int timeout = ((Integer)args[0]).intValue();
- return ((ITransactionFactory)servant).create(targetId, timeout);
- }
- };
-
- /** Invoker for TransactionFactory.recreate */
- static final Invoker RECREATE = new Invoker()
- {
- public Object invoke(Object servant, long targetId, Object[] args)
- throws Throwable
- {
- TxPropagationContext tpc = (TxPropagationContext)args[0];
- return ((ITransactionFactory)servant).recreate(targetId, tpc);
- }
- };
-
- /** Mirror method for TransactionFactory.create */
- TxPropagationContext create(long targetId, int timeout)
- throws RemoteException;
-
- /** Mirror method for TransactionFactory.recreate */
- TxPropagationContext recreate(long targetId, TxPropagationContext tpc)
- throws RemoteException;
-
- }
-
- /**
- * This interface mirrors the interface <code>Coordinator</code> in
- * <code>org.jboss.tm.remoting.interfaces</code>. Attention: method id
- * constants (<code>M_</code>* fields) are indices to an invoker array,
- * so they must be consecutive integers in the range 0..max_index. They
- * also must to be unique among all mirror interfaces.
- */
- public static interface ICoordinator
- {
- /** Method id for Coordinator.getStatus */
- static final int M_GET_STATUS = 2;
-
- /** Method id for Coordinator.isSameTransaction */
- static final int M_IS_SAME_TRANSACTION = 3;
-
- /** Method id for Coordinator.hashTransaction */
- static final int M_HASH_TRANSACTION = 4;
-
- /** Method id for Coordinator.registerResource */
- static final int M_REGISTER_RESOURCE = 5;
-
- /** Method id for Coordinator.registerSynchronization */
- static final int M_REGISTER_SYNCHRONIZATION = 6;
-
- /** Method id for Coordinator.rollbackOnly */
- static final int M_ROLLBACK_ONLY = 7;
-
- /** Method id for Coordinator.getTransactionContext */
- static final int M_GET_TRANSACTION_CONTEXT = 8;
-
- /** Method id for Coordinator.getTransactionId */
- static final int M_GET_TRANSACTION_ID = 9;
-
- /** Invoker for Coordinator.getStatus */
- static final Invoker GET_STATUS = new Invoker()
- {
- public Object invoke(Object servant, long targetId, Object[] args)
- throws Throwable
- {
- return ((ICoordinator)servant).getStatus(targetId);
- }
- };
-
- /** Invoker for Coordinator.isSameTransaction */
- static final Invoker IS_SAME_TRANSACTION = new Invoker()
- {
- public Object invoke(Object servant, long targetId, Object[] args)
- throws Throwable
- {
- Coordinator other = (Coordinator)args[0];
- boolean retVal =
- ((ICoordinator)servant).isSameTransaction(targetId, other);
- return Boolean.valueOf(retVal);
- }
- };
-
- /** Invoker for Coordinator.hashTransaction */
- static final Invoker HASH_TRANSACTION = new Invoker()
- {
- public Object invoke(Object servant, long targetId, Object[] args)
- throws Throwable
- {
- int retVal = ((ICoordinator)servant).hashTransaction(targetId);
- return new Integer(retVal);
- }
- };
-
- /** Invoker for Coordinator.registerResource */
- static final Invoker REGISTER_RESOURCE = new Invoker()
- {
- public Object invoke(Object servant, long targetId, Object[] args)
- throws Throwable
- {
- Resource r = (Resource)args[0];
- return ((ICoordinator)servant).registerResource(targetId, r);
- }
- };
-
- /** Invoker for Coordinator.registerSynchronization */
- static final Invoker REGISTER_SYNCHRONIZATION = new Invoker()
- {
- public Object invoke(Object servant, long targetId, Object[] args)
- throws Throwable
- {
- Synchronization sync = (Synchronization)args[0];
- ((ICoordinator)servant).registerSynchronization(targetId, sync);
- return null;
- }
- };
-
- /** Invoker for Coordinator.rollbackOnly */
- static final Invoker ROLLBACK_ONLY = new Invoker()
- {
- public Object invoke(Object servant, long targetId, Object[] args)
- throws Throwable
- {
- ((ICoordinator)servant).rollbackOnly(targetId);
- return null;
- }
- };
-
- /** Invoker for Coordinator.getTransactionContext */
- static final Invoker GET_TRANSACTION_CONTEXT = new Invoker()
- {
- public Object invoke(Object servant, long targetId, Object[] args)
- throws Throwable
- {
- return ((ICoordinator)servant).getTransactionContext(targetId);
- }
- };
-
- /** Invoker for Coordinator.getTransactionId */
- static final Invoker GET_TRANSACTION_ID = new Invoker()
- {
- public Object invoke(Object servant, long targetId, Object[] args)
- throws Throwable
- {
- return ((ICoordinator)servant).getTransactionId(targetId);
- }
- };
-
- /** Mirror method for Coordinator.getStatus */
- Status getStatus(long targetId)
- throws RemoteException;
-
- /** Mirror method for Coordinator.isSameTransaction */
- boolean isSameTransaction(long targetId, Coordinator c)
- throws RemoteException;
-
- /** Mirror method for Coordinator.hashTransaction */
- int hashTransaction(long targetId)
- throws RemoteException;
-
- /** Mirror method for Coordinator.registerResource */
- RecoveryCoordinator registerResource(long targetId, Resource r)
- throws RemoteException,
- TransactionInactiveException;
-
- /** Mirror method for Coordinator.registerSynchronization */
- void registerSynchronization(long targetId, Synchronization sync)
- throws RemoteException,
- TransactionInactiveException;
-
- /** Mirror method for Coordinator.rollbackOnly */
- void rollbackOnly(long targetId)
- throws RemoteException,
- TransactionInactiveException;
-
- /** Mirror method for Coordinator.getTransactionContext */
- TxPropagationContext getTransactionContext(long targetId)
- throws RemoteException,
- TransactionInactiveException;
-
- /** Mirror method for Coordinator.getTransactionId */
- GlobalId getTransactionId(long targetId)
- throws RemoteException;
- }
-
- /**
- * This interface mirrors the interface <code>Terminator</code> in
- * <code>org.jboss.tm.remoting.interfaces</code>. Attention: method id
- * constants (<code>M_</code>* fields) are indices to an invoker array,
- * so they must be consecutive integers in the range 0..max_index. They
- * also must be unique among all mirror interfaces.
- */
- public static interface ITerminator
- {
- /** Method id for Terminator.commit */
- static final int M_COMMIT = 10;
-
- /** Method id for Terminator.rollback */
- static final int M_ROLLBACK = 11;
-
- /** Invoker for Terminator.commit */
- static final Invoker COMMIT = new Invoker()
- {
- public Object invoke(Object servant, long targetId, Object[] args)
- throws Throwable
- {
- boolean reportHeuristics = ((Boolean)args[0]).booleanValue();
- ((ITerminator)servant).commit(targetId, reportHeuristics);
- return null;
- }
- };
-
- /** Invoker for Terminator.rollback */
- static final Invoker ROLLBACK = new Invoker()
- {
- public Object invoke(Object servant, long targetId, Object[] args)
- throws Throwable
- {
- ((ITerminator)servant).rollback(targetId);
- return null;
- }
- };
-
- /** Mirror method for Terminator.commit */
- void commit(long targetId, boolean reportHeuristics)
- throws RemoteException,
- HeuristicMixedException,
- HeuristicHazardException;
-
- /** Mirror method for Terminator.commit */
- void rollback(long targetId)
- throws RemoteException;
- }
-
- /**
- * This interface mirrors the interface <code>Resource</code> in
- * <code>org.jboss.tm.remoting.interfaces</code>. Attention: method id
- * constants (<code>M_</code>* fields) are indices to an invoker array,
- * so they must be consecutive integers in the range 0..max_index. They
- * also must be unique among all mirror interfaces.
- */
- public static interface IResource
- {
- /** Method id for Resource.prepare */
- static final int M_PREPARE = 12;
-
- /** Method id for Resource.rollback */
- static final int M_ROLLBACK = 13;
-
- /** Method id for Resource.commit */
- static final int M_COMMIT = 14;
-
- /** Method id for Resource.commitOnePhase */
- static final int M_COMMIT_ONE_PHASE = 15;
-
- /** Method id for Resource.forget */
- static final int M_FORGET = 16;
-
- /** Invoker for Resource.prepare */
- static final Invoker PREPARE = new Invoker()
- {
- public Object invoke(Object servant, long targetId, Object[] args)
- throws Throwable
- {
- return ((IResource)servant).prepare(targetId);
- }
- };
-
- /** Invoker for Resource.rollback */
- static final Invoker ROLLBACK = new Invoker()
- {
- public Object invoke(Object servant, long targetId, Object[] args)
- throws Throwable
- {
- ((IResource)servant).rollbackResource(targetId);
- return null;
- }
- };
-
- /** Invoker for Resource.commit */
- static final Invoker COMMIT = new Invoker()
- {
- public Object invoke(Object servant, long targetId, Object[] args)
- throws Throwable
- {
- ((IResource)servant).commit(targetId);
- return null;
- }
- };
-
- /** Invoker for Resource.commitOnePhase */
- static final Invoker COMMIT_ONE_PHASE = new Invoker()
- {
- public Object invoke(Object servant, long targetId, Object[] args)
- throws Throwable
- {
- ((IResource)servant).commitOnePhase(targetId);
- return null;
- }
- };
-
- /** Invoker for Resource.forget */
- static final Invoker FORGET = new Invoker()
- {
- public Object invoke(Object servant, long targetId, Object[] args)
- throws Throwable
- {
- ((IResource)servant).forget(targetId);
- return null;
- }
- };
-
- /** Mirror method for Resource.prepare */
- Vote prepare(long targetId)
- throws RemoteException,
- HeuristicMixedException,
- HeuristicHazardException;
-
- /** Mirror method for Resource.rollback -- its name is rollbackResource
- * (rather than rollback) to avoid the name clash with Terminator.rollback
- * within the DTMServant class */
- void rollbackResource(long targetId)
- throws RemoteException,
- HeuristicCommitException,
- HeuristicMixedException,
- HeuristicHazardException;
-
- /** Mirror method for Resource.commit */
- void commit(long targetId)
- throws RemoteException,
- TransactionNotPreparedException,
- HeuristicRollbackException,
- HeuristicMixedException,
- HeuristicHazardException;
-
- /** Mirror method for Resource.commitOnePhase */
- void commitOnePhase(long targetId)
- throws RemoteException,
- HeuristicHazardException;
-
- /** Mirror method for Resource.forget */
- void forget(long targetId)
- throws RemoteException;
- }
-
- /**
- * This interface mirrors the interface <code>RecoveryCoordinator</code>
- * in <code>org.jboss.tm.remoting.interfaces</code>. Attention: method id
- * constants (<code>M_</code>* fields) are indices to an invoker array,
- * so they must be consecutive integers in the range 0..max_index. They
- * also must be unique among all mirror interfaces.
- */
- public static interface IRecoveryCoordinator
- {
- /** Method id for RecoveryCoordinator.replayCompletion */
- static final int M_REPLAY_COMPLETION = 17;
-
- /** Invoker for RecoveryCoordinator.replayCompletion */
- static final Invoker REPLAY_COMPLETION = new Invoker()
- {
- public Object invoke(Object servant, long targetId, Object[] args)
- throws Throwable
- {
- Resource r = (Resource)args[0];
- return ((IRecoveryCoordinator)servant).replayCompletion(targetId,
- r);
- }
- };
-
- /** Mirror method for RecoveryCoordinator.replayCompletion */
- Status replayCompletion(long targetId, Resource r)
- throws RemoteException,
- TransactionNotPreparedException;
- }
-
- /**
- * This interface mirrors the interface <code>Synchronization</code> in
- * <code>org.jboss.tm.remoting.interfaces</code>. Attention: method id
- * constants (<code>M_</code>* fields) are indices to an invoker array,
- * so they must be consecutive integers in the range 0..max_index. They
- * also must be unique among all mirror interfaces.
- */
- public static interface ISynchronization
- {
- /** Method id for Synchronization.beforeCompletion */
- static final int M_BEFORE_COMPLETION = 18;
-
- /** Method id for Synchronization.afterCompletion */
- static final int M_AFTER_COMPLETION = 19;
-
- /** Invoker for Synchronization.beforeCompletion */
- static final Invoker BEFORE_COMPLETION = new Invoker()
- {
- public Object invoke(Object servant, long targetId, Object[] args)
- throws Throwable
- {
- ((ISynchronization)servant).beforeCompletion(targetId);
- return null;
- }
- };
-
- /** Invoker for Synchronization.afterCompletion */
- static final Invoker AFTER_COMPLETION = new Invoker()
- {
- public Object invoke(Object servant, long targetId, Object[] args)
- throws Throwable
- {
- ((ISynchronization)servant).afterCompletion(targetId);
- return null;
- }
- };
-
- /** Mirror method for Synchronization.beforeCompletion */
- void beforeCompletion(long targetId);
-
- /** Mirror method for Synchronization.afterCompletion */
- void afterCompletion(long targetId);
- }
-
- // Static field --------------------------------------------------
-
- /**
- * Array of <code>Invoker</code> instances ordered by method id.
- * Used for efficient (non-reflective) invocation of a method, given
- * its id.
- */
- private static final Invoker[] invokerArray =
- {
- ITransactionFactory.CREATE,
- ITransactionFactory.RECREATE,
- ICoordinator.GET_STATUS,
- ICoordinator.IS_SAME_TRANSACTION,
- ICoordinator.HASH_TRANSACTION,
- ICoordinator.REGISTER_RESOURCE,
- ICoordinator.REGISTER_SYNCHRONIZATION,
- ICoordinator.ROLLBACK_ONLY,
- ICoordinator.GET_TRANSACTION_CONTEXT,
- ICoordinator.GET_TRANSACTION_ID,
- ITerminator.COMMIT,
- ITerminator.ROLLBACK,
- IResource.PREPARE,
- IResource.ROLLBACK,
- IResource.COMMIT,
- IResource.COMMIT_ONE_PHASE,
- IResource.FORGET,
- IRecoveryCoordinator.REPLAY_COMPLETION,
- ISynchronization.BEFORE_COMPLETION,
- ISynchronization.AFTER_COMPLETION
- };
-
- // Static method--------------------------------------------------
-
- /**
- * Return the id of a given method,
- */
- private static int getMethodId(Method m)
- {
- Class clz = m.getDeclaringClass();
-
- if (clz == TransactionFactory.class)
- {
- String name = m.getName();
-
- if (name.equals("create"))
- return ITransactionFactory.M_CREATE;
- else /* name.equals("recreate") */
- return ITransactionFactory.M_RECREATE;
- }
- else if (clz == Coordinator.class)
- {
- String name = m.getName();
-
- if (name.equals("getStatus"))
- return ICoordinator.M_GET_STATUS;
- else if (name.equals("isSameTransaction"))
- return ICoordinator.M_IS_SAME_TRANSACTION;
- else if (name.equals("hashTransaction"))
- return ICoordinator.M_HASH_TRANSACTION;
- else if (name.equals("registerResource"))
- return ICoordinator.M_REGISTER_RESOURCE;
- else if (name.equals("registerSynchronization"))
- return ICoordinator.M_REGISTER_SYNCHRONIZATION;
- else if (name.equals("rollbackOnly"))
- return ICoordinator.M_ROLLBACK_ONLY;
- else if (name.equals("getTransactionContext"))
- return ICoordinator.M_GET_TRANSACTION_CONTEXT;
- else /* name.equals("getTransactionId") */
- return ICoordinator.M_GET_TRANSACTION_ID;
- }
- else if (clz == Terminator.class)
- {
- String name = m.getName();
-
- if (name.equals("commit"))
- return ITerminator.M_COMMIT;
- else /* name.equals("rollback") */
- return ITerminator.M_ROLLBACK;
-
- }
- else if (clz == Resource.class)
- {
- String name = m.getName();
-
- if (name.equals("prepare"))
- return IResource.M_PREPARE;
- else if (name.equals("rollback"))
- return IResource.M_ROLLBACK;
- else if (name.equals("commit"))
- return IResource.M_COMMIT;
- else if (name.equals("commitOnePhase"))
- return IResource.M_COMMIT_ONE_PHASE;
- else /* name.equals("forget") */
- return IResource.M_FORGET;
- }
- else if (clz == RecoveryCoordinator.class)
- {
- return IRecoveryCoordinator.M_REPLAY_COMPLETION;
- }
- else if (clz == Synchronization.class)
- {
- String name = m.getName();
-
- if (name.equals("beforeCompletion"))
- return ISynchronization.M_BEFORE_COMPLETION;
- else /* name.equals("afterCompletion") */
- return ISynchronization.M_AFTER_COMPLETION;
- }
- else
- {
- throw new RuntimeException("Method " + m + " does not belong to" +
- " a transaction service interface");
- }
- }
-
- // Attributes ----------------------------------------------------
-
- /** Specifies the logical target of this <code>Invocation</code>. */
- private long targetId;
-
- /** Specifies the method to be invoked. */
- private int methodId;
-
- /** The arguments for the method invocation. */
- private Object[] args;
-
- // Constructors --------------------------------------------------
-
- /** Builds a new <code>Invocation</code> instance. */
- public Invocation(long targetId,
- Method method,
- Object[] args)
- {
- this.targetId = targetId;
- this.methodId = getMethodId(method);
- this.args = args;
- }
-
- /** Uses the given servant to perform this <code>Invocation</code>. */
- public Object perform(InvokerLocator locator, Object servant)
- throws Throwable
- {
- return invokerArray[methodId].invoke(servant, targetId, args);
- }
-
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/remoting/RemoteProxy.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/remoting/RemoteProxy.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/remoting/RemoteProxy.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,95 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.remoting;
-
-import java.lang.reflect.Proxy;
-
-import org.jboss.remoting.InvokerLocator;
-
-/**
- * Utility class for creating remote proxies, converting them to strings and
- * converting strings to remote proxies.
- *
- * @author <a href="mailto:reverbel at ime.usp.br">Francisco Reverbel</a>
- * @version $Revision$
- */
-public class RemoteProxy
-{
- /**
- * Create a remote proxy given a DTM interface, a target object id and
- * an array of <code>InvokerLocator</code>s.
- *
- * @param interf the DTM interface to be implemented by the proxy
- * @param oid the id of the remote object proxified
- * @param locators the array of invoker locators
- * @return a newly created proxy
- */
- public static Object create(Class interf,
- long oid,
- InvokerLocator[] locators)
- {
- try
- {
- ClientInvocationHandler handler =
- new ClientInvocationHandler(interf, oid, locators);
- return Proxy.newProxyInstance(interf.getClassLoader(),
- new Class[] { interf },
- handler);
- }
- catch (Exception e)
- {
- e.printStackTrace();
- return null;
- }
- }
-
- /**
- * Converts a DTM proxy to String
- *
- * @param p a DTM proxy
- * @return the string representation of the proxy
- */
- public static String toString(Proxy p)
- {
- ClientInvocationHandler handler =
- (ClientInvocationHandler) Proxy.getInvocationHandler(p);
- return handler.toString();
- }
-
- /**
- * Converts a stringfied DTM proxy back into a proxy instance.
- *
- * @param s the string representation of a DTM proxy
- * @return a DTM proxy
- * @throws Exception
- */
- public static Object fromString(String s)
- throws Exception
- {
- ClientInvocationHandler handler = ClientInvocationHandler.fromString(s);
- Class interf = handler.getClientInterface();
- return Proxy.newProxyInstance(interf.getClassLoader(),
- new Class[] { interf },
- handler);
- }
-
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/remoting/client/ClientUserTransaction.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/remoting/client/ClientUserTransaction.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/remoting/client/ClientUserTransaction.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,371 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.remoting.client;
-
-import java.io.Serializable;
-import java.rmi.AccessException;
-import java.rmi.NoSuchObjectException;
-import java.rmi.RemoteException;
-
-import javax.naming.Context;
-import javax.naming.InitialContext;
-import javax.naming.NamingException;
-import javax.naming.Reference;
-import javax.naming.Referenceable;
-import javax.transaction.HeuristicMixedException;
-import javax.transaction.HeuristicRollbackException;
-import javax.transaction.NotSupportedException;
-import javax.transaction.RollbackException;
-import javax.transaction.SystemException;
-import javax.transaction.Transaction;
-import javax.transaction.TransactionRolledbackException;
-import javax.transaction.UserTransaction;
-
-import org.jboss.tm.TransactionPropagationContextFactory;
-import org.jboss.tm.remoting.interfaces.HeuristicHazardException;
-import org.jboss.tm.remoting.interfaces.Status;
-import org.jboss.tm.remoting.interfaces.TransactionFactory;
-import org.jboss.tm.remoting.interfaces.TransactionInactiveException;
-import org.jboss.tm.remoting.interfaces.TxPropagationContext;
-
-
-/**
- * The client-side UserTransaction implementation for JBoss remoting clients.
- * This will delegate all UserTransaction calls to the DTM in the server.
- *
- * <em>Warning:</em> This is only for stand-alone JBoss remoting clients that
- * do not have their own transaction service. No local work is done in
- * the context of transactions started here, only work done in beans
- * at the server.
- *
- * @author <a href="mailto:reverbel at ime.usp.br">Francisco Reverbel</a>
- * @version $Revision$
- */
-public class ClientUserTransaction
- implements UserTransaction,
- TransactionPropagationContextFactory,
- Referenceable,
- Serializable
-{
- // Static --------------------------------------------------------
-
- static final long serialVersionUID = -3704980350844202097L;
-
- /** Our singleton instance. */
- private static ClientUserTransaction singleton = null;
-
- /** The JNDI name to which the server's transaction factory proxy is bound */
- public static final String TX_FACTORY_JNDI_NAME = "DTMTransactionFactory";
-
- /** Remote proxy to the server's transaction factory. */
- private static TransactionFactory txFactory;
-
- /** Transaction information associated with the current thread. */
- private static ThreadLocal threadLocalData = new ThreadLocal() {
- protected synchronized Object initialValue()
- {
- return new TransactionInfo(); // see nested class below
- }
- };
-
- // Nested class -------------------------------------------------
-
- /**
- * The <code>TransactionInfo</code> class holds transaction information
- * associated with the current thread. The <code>threadLocalData</code>
- * field contains an instance of this class. The field timeout applies
- * to new transactions started by the current thread; its value is not
- * necessarily equal to the time out of the currrent transaction. The
- * <code>TxPropagationContext</code> field refers to the currrent
- * transaction.
- */
- private static class TransactionInfo
- {
- int timeout = 0; // for new transactions started by the current thread
- TxPropagationContext tpc; // null if no current transaction
- }
-
- // Static accessors to thread-local data -------------------------
-
- private static void setThreadLocalTimeout(int timeout)
- {
- ((TransactionInfo)threadLocalData.get()).timeout = timeout;
- }
-
- private static int getThreadLocalTimeout()
- {
- return ((TransactionInfo)threadLocalData.get()).timeout;
- }
-
- private static void setThreadLocalTPC(TxPropagationContext tpc)
- {
- ((TransactionInfo)threadLocalData.get()).tpc = tpc;
- }
-
- private static TxPropagationContext getThreadLocalTPC()
- throws IllegalStateException
- {
- return ((TransactionInfo)threadLocalData.get()).tpc;
- }
-
- // Other auxiliary (and static) methods -------------------------
-
- /**
- * Returns a CORBA reference to the TransactionFactory implemented by
- * the JBoss server.
- */
- private static TransactionFactory getTxFactory()
- {
- if (txFactory == null)
- {
- try
- {
- Context ctx = new InitialContext();
- txFactory = (TransactionFactory) ctx.lookup(TX_FACTORY_JNDI_NAME);
- }
- catch (Exception e)
- {
- throw new RuntimeException("Could not get transaction factory: ", e);
- }
- }
- return txFactory;
- }
-
- /**
- * Converts transaction status from org.omg.CosTransactions format
- * to javax.transaction format.
- */
- private static int jbossToJavax(Status status)
- {
- return status.toInteger();
- }
-
- // Constructors --------------------------------------------------
-
- /**
- * Create a new instance.
- */
- private ClientUserTransaction()
- {
- }
-
- // Public --------------------------------------------------------
-
- /**
- * Returns a reference to the singleton instance.
- */
- public static ClientUserTransaction getSingleton()
- {
- if (singleton == null)
- singleton = new ClientUserTransaction();
- return singleton;
- }
-
- //
- // Implementation of interface UserTransaction
- //
-
- public void begin()
- throws NotSupportedException, SystemException
- {
- if (getThreadLocalTPC() != null)
- throw new NotSupportedException();
- try
- {
- TxPropagationContext tpc =
- getTxFactory().create(getThreadLocalTimeout());
- setThreadLocalTPC(tpc);
- }
- catch (RemoteException e)
- {
- SystemException e2 = new SystemException("Unable to begin transaction");
- e2.initCause(e);
- throw e2;
- }
- }
-
- public void commit()
- throws RollbackException,
- HeuristicMixedException,
- HeuristicRollbackException,
- SecurityException,
- IllegalStateException,
- SystemException
- {
- try
- {
- TxPropagationContext tpc = getThreadLocalTPC();
-
- if (tpc == null)
- throw new IllegalStateException();
-
- tpc.terminator.commit(true /* reportHeuristics */);
- }
- catch (TransactionRolledbackException e)
- {
- RollbackException e2 = new RollbackException("Transaction rolled back");
- e2.initCause(e);
- throw e2;
- }
- catch (HeuristicHazardException e)
- {
- HeuristicRollbackException e2 = new HeuristicRollbackException("Heuristic hazard");
- e2.initCause(e);
- throw e2;
- }
- catch (AccessException e)
- {
- SecurityException e2 = new SecurityException("Access denied");
- e2.initCause(e);
- throw e2;
- }
- catch (RemoteException e)
- {
- SystemException e2 = new SystemException("Error during commit");
- e2.initCause(e);
- throw e2;
- }
- finally
- {
- setThreadLocalTPC(null);
- }
- }
-
- public void rollback()
- throws SecurityException,
- IllegalStateException,
- SystemException
- {
- try
- {
- TxPropagationContext tpc = getThreadLocalTPC();
-
- if (tpc == null)
- throw new IllegalStateException();
-
- tpc.terminator.rollback();
- }
- catch (AccessException e)
- {
- SecurityException e2 = new SecurityException("Access denied");
- e2.initCause(e);
- throw e2;
- }
- catch (RemoteException e)
- {
- SystemException e2 = new SystemException("Error during rollback");
- e2.initCause(e);
- throw e2;
- }
- finally
- {
- setThreadLocalTPC(null);
- }
- }
-
- public void setRollbackOnly()
- throws IllegalStateException,
- SystemException
- {
- try
- {
- TxPropagationContext tpc = getThreadLocalTPC();
-
- if (tpc == null)
- throw new IllegalStateException();
-
- tpc.coordinator.rollbackOnly();
- }
- catch (TransactionInactiveException e)
- {
- IllegalStateException e2 = new IllegalStateException("Transaction is not active");
- e2.initCause(e);
- throw e2;
- }
- catch (RemoteException e)
- {
- SystemException e2 = new SystemException("Error during rollback");
- e2.initCause(e);
- throw e2;
- }
- }
-
- public int getStatus()
- throws SystemException
- {
- try
- {
- TxPropagationContext tpc = getThreadLocalTPC();
-
- if (tpc == null)
- return javax.transaction.Status.STATUS_NO_TRANSACTION;
- else
- return jbossToJavax(tpc.coordinator.getStatus());
- }
- catch (NoSuchObjectException e)
- {
- return javax.transaction.Status.STATUS_NO_TRANSACTION;
- }
- catch (RemoteException e)
- {
- SystemException e2 = new SystemException("Error getting status");
- e2.initCause(e);
- throw e2;
- }
- }
-
- public void setTransactionTimeout(int seconds)
- throws SystemException
- {
- setThreadLocalTimeout(seconds);
- }
-
- //
- // implements interface TransactionPropagationContextFactory
- //
-
- public Object getTransactionPropagationContext()
- {
- return getThreadLocalTPC();
- }
-
- public Object getTransactionPropagationContext(Transaction tx)
- {
- // No need to implement in a stand-alone client.
- throw new InternalError("Should not have been used.");
- }
-
- //
- // Implementation of interface Referenceable
- //
-
- public Reference getReference()
- throws NamingException
- {
- Reference ref = new Reference(
- "org.jboss.tm.remoting.client.ClientUserTransaction",
- "org.jboss.tm.remoting.client.ClientUserTransactionObjectFactory",
- null);
- return ref;
- }
-
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/remoting/client/ClientUserTransactionObjectFactory.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/remoting/client/ClientUserTransactionObjectFactory.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/remoting/client/ClientUserTransactionObjectFactory.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,92 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.remoting.client;
-
-import org.jboss.tm.TransactionPropagationContextUtil;
-import org.jboss.tm.usertx.client.ServerVMClientUserTransaction;
-
-import java.util.Hashtable;
-
-import javax.naming.Context;
-import javax.naming.InitialContext;
-import javax.naming.Reference;
-import javax.naming.Name;
-import javax.naming.NamingException;
-import javax.naming.spi.ObjectFactory;
-
-import javax.transaction.UserTransaction;
-
-/**
- * This is an object factory for producing client <code>UserTransaction</code>
- * instances.
- *
- * @author <a href="mailto:osh at sparre.dk">Ole Husgaard</a>
- * @version $Revision$
- */
-public class ClientUserTransactionObjectFactory
- implements ObjectFactory
-{
- /**
- * The <code>UserTransaction</code> this factory will return.
- * This is evaluated lazily in {@link #getUserTransaction()}.
- */
- static private UserTransaction userTransaction = null;
-
- /**
- * Get the <code>UserTransaction</code> this factory will return.
- * This may return a cached value from a previous call.
- */
- static private UserTransaction getUserTransaction()
- {
- if (userTransaction == null) {
- // See if we have a local TM
- try {
- new InitialContext().lookup("java:/TransactionManager");
-
- // We execute in the server.
- userTransaction = ServerVMClientUserTransaction.getSingleton();
- } catch (NamingException ex) {
- // We execute in a stand-alone client.
- ClientUserTransaction cut = ClientUserTransaction.getSingleton();
-
- // Tell the proxy that this is the factory for
- // transaction propagation contexts.
- TransactionPropagationContextUtil.setTPCFactory(cut);
- userTransaction = cut;
- }
- }
- return userTransaction;
- }
-
- public Object getObjectInstance(Object obj, Name name,
- Context nameCtx, Hashtable environment)
- throws Exception
- {
- Reference ref = (Reference)obj;
-
- if (!ref.getClassName().equals(ClientUserTransaction.class.getName()))
- return null;
-
- return getUserTransaction();
- }
-}
-
Deleted: trunk/transaction/src/main/org/jboss/tm/remoting/interfaces/Coordinator.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/remoting/interfaces/Coordinator.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/remoting/interfaces/Coordinator.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,67 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.remoting.interfaces;
-
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-
-import org.jboss.tm.GlobalId;
-
-/**
- * Interface used by the participants in a transaction.
- *
- * @author <a href="mailto:reverbel at ime.usp.br">Francisco Reverbel</a>
- * @version $Revision$
- */
-public interface Coordinator extends Remote
-{
-
- Status getStatus()
- throws RemoteException;
-
- boolean isSameTransaction(Coordinator c)
- throws RemoteException;
-
- int hashTransaction()
- throws RemoteException;
-
- RecoveryCoordinator registerResource(Resource r)
- throws RemoteException,
- TransactionInactiveException;
-
- void registerSynchronization(Synchronization sync)
- throws RemoteException,
- TransactionInactiveException,
- SynchronizationUnavailableException;
-
- void rollbackOnly()
- throws RemoteException,
- TransactionInactiveException;
-
- TxPropagationContext getTransactionContext()
- throws RemoteException,
- TransactionInactiveException;
-
- GlobalId getTransactionId()
- throws RemoteException;
-
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/remoting/interfaces/HeuristicHazardException.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/remoting/interfaces/HeuristicHazardException.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/remoting/interfaces/HeuristicHazardException.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,52 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.remoting.interfaces;
-
-/**
- * Indicates that a heuristic decision may have been made, the disposition of
- * all relevant updates is not known, and for those updates whose disposition
- * is knwon, either all have been committed or all have been rolled back. (In
- * other words, the <code>HeuristicMixed</code> exception takes priority over
- * this exception.
- *
- * @author <a href="reverbel at ime.usp.br">Francisco Reverbel</a>
- * @version $Revision$
- */
-public class HeuristicHazardException extends Exception
-{
- private static final long serialVersionUID = -3687274256195397687L;
-
- public HeuristicHazardException()
- {
- }
-
- public HeuristicHazardException(String msg)
- {
- super(msg);
- }
-
- public HeuristicHazardException(Throwable cause)
- {
- super(cause);
- }
-
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/remoting/interfaces/RecoveryCoordinator.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/remoting/interfaces/RecoveryCoordinator.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/remoting/interfaces/RecoveryCoordinator.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,41 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.remoting.interfaces;
-
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-
-
-/**
- * Interface that allows a recoverable object to drive the recovery process.
- *
- * @author <a href="mailto:reverbel at ime.usp.br">Francisco Reverbel</a>
- * @version $Revision$
- */
-public interface RecoveryCoordinator extends Remote
-{
-
- Status replayCompletion(Resource r)
- throws RemoteException,
- TransactionNotPreparedException;
-}
-
Deleted: trunk/transaction/src/main/org/jboss/tm/remoting/interfaces/Resource.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/remoting/interfaces/Resource.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/remoting/interfaces/Resource.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,68 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.remoting.interfaces;
-
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-
-import javax.transaction.HeuristicCommitException;
-import javax.transaction.HeuristicMixedException;
-import javax.transaction.HeuristicRollbackException;
-
-
-/**
- * Interface that provides operations invoked by the transaction service
- * on each resource.
- *
- * @author <a href="mailto:reverbel at ime.usp.br">Francisco Reverbel</a>
- * @version $Revision$
- */
-public interface Resource extends Remote
-{
-
- Vote prepare()
- throws RemoteException,
- TransactionAlreadyPreparedException,
- HeuristicMixedException,
- HeuristicHazardException;
-
- void rollback()
- throws RemoteException,
- HeuristicCommitException,
- HeuristicMixedException,
- HeuristicHazardException;
-
- void commit()
- throws RemoteException,
- TransactionNotPreparedException,
- HeuristicRollbackException,
- HeuristicMixedException,
- HeuristicHazardException;
-
- void commitOnePhase()
- throws RemoteException,
- HeuristicHazardException;
-
- void forget()
- throws RemoteException;
-
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/remoting/interfaces/Status.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/remoting/interfaces/Status.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/remoting/interfaces/Status.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,105 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.remoting.interfaces;
-
-import java.io.ObjectStreamException;
-import java.io.Serializable;
-
-/**
- * Type safe enumeration for the status of a transaction.
- *
- * @author Scott.Stark at jboss.org
- * @author <a href="mailto:reverbel at ime.usp.br">Francisco Reverbel</a>
- * @version $Revision$
- */
-public class Status implements Serializable
-{
- static final long serialVersionUID = -498123265225476852L;
-
- /**
- * The max ordinal value in use for the Status enums. When you add a
- * new key enum value you must assign it an ordinal value of the current
- * MAX_TYPE_ID+1 and update the MAX_TYPE_ID value.
- */
- private static final int MAX_TYPE_ID = 9;
-
- /** The array of Status indexed by ordinal value of the key */
- private static final Status[] values = new Status[MAX_TYPE_ID + 1];
-
- // IMPORTANT: The ordinal values below are equal to the corresponding
- // values in org.omg.CosTransactions.Status and in javax.transaction.Status.
- // This allows efficient conversion between
- // org.jboss.tm.remoting.interfaces.Status instances
- // and org.omg.CosTransactions.Status or javax.transaction.Status instances.
- public static final Status ACTIVE = new Status("ACTIVE", 0);
-
- public static final Status MARKED_ROLLBACK = new Status("MARKED_ROLLBACK", 1);
-
- public static final Status PREPARED = new Status("PREPARED", 2);
-
- public static final Status COMMITTED = new Status("COMMITTED", 3);
-
- public static final Status ROLLEDBACK = new Status("ROLLEDBACK", 4);
-
- public static final Status UNKNOWN = new Status("UNKNOWN", 5);
-
- public static final Status NO_TRANSACTION = new Status("NO_TRANSACTION", 6);
-
- public static final Status PREPARING = new Status("PREPARING", 7);
-
- public static final Status COMMITTING = new Status("COMMITTING", 8);
-
- public static final Status ROLLINGBACK = new Status("ROLLINGBACK", 9);
-
- private final transient String name;
-
- // this is the only value serialized
- private final int ordinal;
-
- private Status(String name, int ordinal)
- {
- this.name = name;
- this.ordinal = ordinal;
- values[ordinal] = this;
- }
-
- public String toString()
- {
- return name;
- }
-
- public int toInteger()
- {
- return ordinal;
- }
-
- public static Status fromInteger(int i)
- {
- return values[i];
- }
-
- Object readResolve() throws ObjectStreamException
- {
- return values[ordinal];
- }
-
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/remoting/interfaces/Synchronization.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/remoting/interfaces/Synchronization.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/remoting/interfaces/Synchronization.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,43 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.remoting.interfaces;
-
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-
-/**
- * Interface implemented by objects that want to be notified before the start
- * of the two-phase commit protocol, and after its competion.
- *
- * @author <a href="mailto:reverbel at ime.usp.br">Francisco Reverbel</a>
- * @version $Revision$
- */
-public interface Synchronization extends Remote
-{
-
- void beforeCompletion()
- throws RemoteException;
-
- void afterCompletion(Status s)
- throws RemoteException;
-
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/remoting/interfaces/SynchronizationUnavailableException.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/remoting/interfaces/SynchronizationUnavailableException.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/remoting/interfaces/SynchronizationUnavailableException.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,35 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.remoting.interfaces;
-
-/**
- * Exception thrown by <code>Coordinator.registerSynchronization</code>
- * to indicate that the target coordinator does not support synchronization
- * callbacks.
- *
- * @author <a href="mailto:reverbel at ime.usp.br">Francisco Reverbel</a>
- * @version $Revision$
- */
-public class SynchronizationUnavailableException extends Exception
-{
- static final long serialVersionUID = -4736175108426365516L;
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/remoting/interfaces/Terminator.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/remoting/interfaces/Terminator.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/remoting/interfaces/Terminator.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,47 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.remoting.interfaces;
-
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-
-import javax.transaction.HeuristicMixedException;
-
-
-/**
- * Interface that provides operations to commit or rollback a transaction.
- *
- * @author <a href="mailto:reverbel at ime.usp.br">Francisco Reverbel</a>
- * @version $Revision$
- */
-public interface Terminator extends Remote
-{
-
- void commit(boolean reportHeuristics)
- throws RemoteException,
- HeuristicMixedException,
- HeuristicHazardException;
-
- void rollback()
- throws RemoteException;
-
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/remoting/interfaces/TransactionAlreadyPreparedException.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/remoting/interfaces/TransactionAlreadyPreparedException.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/remoting/interfaces/TransactionAlreadyPreparedException.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,49 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.remoting.interfaces;
-
-/**
- * Exception thrown when <code>prepare</code> is called on a resource that is
- * already prepared.
- *
- * @author <a href="mailto:reverbel at ime.usp.br">Francisco Reverbel</a>
- * @version $Revision$
- */
-public class TransactionAlreadyPreparedException extends Exception
-{
- static final long serialVersionUID = 7862561036798964308L;
-
- public TransactionAlreadyPreparedException()
- {
- }
-
- public TransactionAlreadyPreparedException(String msg)
- {
- super(msg);
- }
-
- public TransactionAlreadyPreparedException(Throwable cause)
- {
- super(cause);
- }
-
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/remoting/interfaces/TransactionFactory.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/remoting/interfaces/TransactionFactory.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/remoting/interfaces/TransactionFactory.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,43 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.remoting.interfaces;
-
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-
-
-/**
- * Interface that allows the transaction originator to begin a transaction.
- *
- * @author <a href="mailto:reverbel at ime.usp.br">Francisco Reverbel</a>
- * @version $Revision$
- */
-public interface TransactionFactory extends Remote
-{
-
- TxPropagationContext create(int timeout)
- throws RemoteException;
-
- TxPropagationContext recreate(TxPropagationContext tpc)
- throws RemoteException;
-
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/remoting/interfaces/TransactionInactiveException.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/remoting/interfaces/TransactionInactiveException.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/remoting/interfaces/TransactionInactiveException.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,49 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.remoting.interfaces;
-
-/**
- * Indicates that a transaction expected to be in the active state
- * has already been prepared for commit or marked for rollback.
- *
- * @author <a href="mailto:reverbel at ime.usp.br">Francisco Reverbel</a>
- * @version $Revision$
- */
-public class TransactionInactiveException extends Exception
-{
- static final long serialVersionUID = -846122012000355051L;
-
- public TransactionInactiveException()
- {
- }
-
- public TransactionInactiveException(String msg)
- {
- super(msg);
- }
-
- public TransactionInactiveException(Throwable cause)
- {
- super(cause);
- }
-
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/remoting/interfaces/TransactionNotPreparedException.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/remoting/interfaces/TransactionNotPreparedException.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/remoting/interfaces/TransactionNotPreparedException.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,49 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.remoting.interfaces;
-
-/**
- * Indicates that a transaction expected to be in the prepared state
- * is actually not prepared.
- *
- * @author <a href="mailto:reverbel at ime.usp.br">Francisco Reverbel</a>
- * @version $Revision$
- */
-public class TransactionNotPreparedException extends Exception
-{
- static final long serialVersionUID = -4131393859923384723L;
-
- public TransactionNotPreparedException()
- {
- }
-
- public TransactionNotPreparedException(String msg)
- {
- super(msg);
- }
-
- public TransactionNotPreparedException(Throwable cause)
- {
- super(cause);
- }
-
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/remoting/interfaces/TxPropagationContext.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/remoting/interfaces/TxPropagationContext.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/remoting/interfaces/TxPropagationContext.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,85 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.remoting.interfaces;
-
-import java.io.Serializable;
-
-
-/**
- * The <code>TransactionFactory</code> operations return instances of this
- * class, which defines the transaction context to be propagated along with
- * outgoing invocations issued through the remoting framework. In the IIOP
- * case, however, the transaction context is not propagated as a
- * <code>TxPropagationContext</code> instance, but in the standard format
- * defined by the CORBA Transaction Service specification.
- *
- * @author <a href="mailto:reverbel at ime.usp.br">Francisco Reverbel</a>
- * @version $Revision$
- */
-public class TxPropagationContext implements Serializable
-{
- static final long serialVersionUID = 88513087659796235L;
-
- private static String thisClassName;
-
- static {
- thisClassName = TxPropagationContext.class.getName();
- thisClassName =
- thisClassName.substring(thisClassName.lastIndexOf('.') + 1);
- }
-
- public int formatId;
- public byte[] globalId;
- public int timeout;
- public Coordinator coordinator;
- public Terminator terminator;
-
- public TxPropagationContext(int formatId,
- byte[] globalId,
- int timeout,
- Coordinator coordinator,
- Terminator terminator)
-
- {
- this.formatId = formatId;
- this.globalId = globalId;
- this.timeout = timeout;
- this.coordinator = coordinator;
- this.terminator = terminator;
- }
-
- public TxPropagationContext(int formatId,
- byte[] globalId,
- int timeout,
- Coordinator coordinator)
- {
- this(formatId, globalId, timeout, coordinator, null);
- }
-
- public String toString()
- {
- return thisClassName + "[formatId=" + formatId
- + ", globalId=" + new String(globalId).trim()
- + ", timeout=" + timeout + "]";
- }
-
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/remoting/interfaces/Vote.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/remoting/interfaces/Vote.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/remoting/interfaces/Vote.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,74 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.remoting.interfaces;
-
-import java.io.ObjectStreamException;
-import java.io.Serializable;
-
-/**
- * Type safe enumeration for <code>Resource</code> votes.
- *
- * @author Scott.Stark at jboss.org
- * @author <a href="mailto:reverbel at ime.usp.br">Francisco Reverbel</a>
- * @version $Revision$
- */
-public class Vote implements Serializable
-{
- static final long serialVersionUID = -6997498750766547785L;
-
- /**
- * The max ordinal value in use for the Vote enums. When you add a
- * new key enum value you must assign it an ordinal value of the current
- * MAX_TYPE_ID+1 and update the MAX_TYPE_ID value.
- */
- private static final int MAX_TYPE_ID = 2;
-
- /** The array of Vote indexed by ordinal value of the key */
- private static final Vote[] values = new Vote[MAX_TYPE_ID + 1];
-
- public static final Vote COMMIT = new Vote("COMMIT", 0);
- public static final Vote ROLLBACK = new Vote("ROLLBACK", 1);
- public static final Vote READONLY = new Vote("READONLY", 2);
-
- private final transient String name;
-
- // this is the only value serialized
- private final int ordinal;
-
- private Vote(String name, int ordinal)
- {
- this.name = name;
- this.ordinal = ordinal;
- values[ordinal] = this;
- }
-
- public String toString()
- {
- return name;
- }
-
- Object readResolve() throws ObjectStreamException
- {
- return values[ordinal];
- }
-
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/remoting/server/DTMInvocationHandler.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/remoting/server/DTMInvocationHandler.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/remoting/server/DTMInvocationHandler.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,93 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.remoting.server;
-
-import javax.management.MBeanServer;
-
-import org.jboss.remoting.InvocationRequest;
-import org.jboss.remoting.ServerInvocationHandler;
-import org.jboss.remoting.ServerInvoker;
-import org.jboss.remoting.callback.InvokerCallbackHandler;
-import org.jboss.tm.remoting.Invocation;
-
-/**
- * <code>ServerInvocationHandler</code> for the DTM subsystem.
- *
- * @author <a href="mailto:reverbel at ime.usp.br">Francisco Reverbel</a>
- * @version $Revision$
- */
-public class DTMInvocationHandler implements ServerInvocationHandler
-{
- private DTMServant dtmServant;
- private ServerInvoker invoker;
-
- DTMInvocationHandler(DTMServant dtmServant)
- {
- this.dtmServant = dtmServant;
- }
-
- /**
- * Empty method - this invocation handler does not keep a reference to the <code>MBeanServer</code>.
- * @see org.jboss.remoting.ServerInvocationHandler#setMBeanServer(javax.management.MBeanServer)
- */
- public void setMBeanServer(MBeanServer server)
- {
- }
-
- /**
- * Sets this invovation handler's <code>ServerInvoker</code>.
- * @see org.jboss.remoting.ServerInvocationHandler#setInvoker(org.jboss.remoting.ServerInvoker)
- */
- public void setInvoker(ServerInvoker invoker)
- {
- this.invoker = invoker;
- }
-
- /**
- * Performs the invocation specified by a given <code>InvocationRequest</code>,
- * @see org.jboss.remoting.ServerInvocationHandler#invoke(org.jboss.remoting.InvocationRequest)
- */
- public Object invoke(InvocationRequest invocationRequest)
- throws Throwable
- {
- Invocation invocation = (Invocation)invocationRequest.getParameter();
-
- return invocation.perform(invoker.getLocator(), dtmServant);
- }
-
- /**
- * Empty method - listener registration is not supported.
- * @see org.jboss.remoting.ServerInvocationHandler#addListener(org.jboss.remoting.callback.InvokerCallbackHandler)
- */
- public void addListener(InvokerCallbackHandler callbackHandler)
- {
- }
-
- /**
- * Empty method - listener registration is not supported.
- * @see org.jboss.remoting.ServerInvocationHandler#removeListener(org.jboss.remoting.callback.InvokerCallbackHandler)
- */
- public void removeListener(InvokerCallbackHandler callbackHandler)
- {
- }
-
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/remoting/server/DTMServant.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/remoting/server/DTMServant.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/remoting/server/DTMServant.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,967 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.remoting.server;
-
-import java.lang.reflect.Proxy;
-import java.rmi.AccessException;
-import java.rmi.NoSuchObjectException;
-import java.rmi.RemoteException;
-import java.rmi.UnexpectedException;
-
-import javax.transaction.HeuristicCommitException;
-import javax.transaction.HeuristicMixedException;
-import javax.transaction.HeuristicRollbackException;
-import javax.transaction.NotSupportedException;
-import javax.transaction.RollbackException;
-import javax.transaction.SystemException;
-import javax.transaction.Transaction;
-import javax.transaction.TransactionManager;
-import javax.transaction.TransactionRolledbackException;
-import javax.transaction.xa.XAResource;
-
-import org.jboss.logging.Logger;
-import org.jboss.tm.CoordinatorFactory;
-import org.jboss.tm.GlobalId;
-import org.jboss.tm.LocalId;
-import org.jboss.tm.ResourceFactory;
-import org.jboss.tm.StringRemoteRefConverter;
-import org.jboss.tm.TransactionImpl;
-import org.jboss.tm.TMUtil;
-import org.jboss.tm.TxManager;
-import org.jboss.tm.XidImpl;
-import org.jboss.tm.remoting.RemoteProxy;
-import org.jboss.tm.remoting.Invocation.ICoordinator;
-import org.jboss.tm.remoting.Invocation.IRecoveryCoordinator;
-import org.jboss.tm.remoting.Invocation.IResource;
-import org.jboss.tm.remoting.Invocation.ISynchronization;
-import org.jboss.tm.remoting.Invocation.ITerminator;
-import org.jboss.tm.remoting.Invocation.ITransactionFactory;
-import org.jboss.tm.remoting.interfaces.Coordinator;
-import org.jboss.tm.remoting.interfaces.HeuristicHazardException;
-import org.jboss.tm.remoting.interfaces.RecoveryCoordinator;
-import org.jboss.tm.remoting.interfaces.Resource;
-import org.jboss.tm.remoting.interfaces.Status;
-import org.jboss.tm.remoting.interfaces.Synchronization;
-import org.jboss.tm.remoting.interfaces.Terminator;
-import org.jboss.tm.remoting.interfaces.TxPropagationContext;
-import org.jboss.tm.remoting.interfaces.TransactionInactiveException;
-import org.jboss.tm.remoting.interfaces.TransactionNotPreparedException;
-import org.jboss.tm.remoting.interfaces.Vote;
-
-/**
- * Remoting servant for the following Distributed Transaction Manager
- * interfaces: <code>TransactionFactory</code>, <code>Coordinator</code>,
- * <code>Terminator</code>, <code>RecoveryCoordinator</code>,
- * <code>Synchronization</code>.
- *
- * @author <a href="mailto:reverbel at ime.usp.br">Francisco Reverbel</a>
- * @version $Revision$
- */
-public class DTMServant implements ITransactionFactory,
- ICoordinator,
- ITerminator,
- IResource,
- IRecoveryCoordinator,
- ISynchronization,
- CoordinatorFactory,
- ResourceFactory,
- StringRemoteRefConverter
-{
-
- // Constants ----------------------------------------------------
-
- private static final Logger log =
- Logger.getLogger(DTMServant.class);
-
- // Private fields ------------------------------------------------
-
- private DistributedTransactionManager dtm;
-
- // Constructor ---------------------------------------------------
-
- public DTMServant(DistributedTransactionManager dtm)
- {
- this.dtm = dtm;
- }
-
- // ITransactionFactory methods -----------------------------------
-
- public TxPropagationContext create(long targetId, int timeout)
- throws RemoteException
- {
- log.trace("TransactionFactory.create");
- try
- {
- TransactionManager tm = TMUtil.getTransactionManager();
-
- // Set timeout value
- if (timeout != 0)
- tm.setTransactionTimeout(timeout);
-
- // Start tx
- tm.begin();
-
- // Suspend thread association
- // and get the xid and the local id of the transaction
- TransactionImpl tx = (TransactionImpl)tm.suspend();
- XidImpl xid = tx.getXid();
- long localId = xid.getLocalIdValue();
-
- // Get the TxPropagationContext of the transaction
- TxPropagationContext tpc = tx.getPropagationContext();
-
- // Set the terminator in the TPC and return the TPC
- tpc.terminator =
- (Terminator) RemoteProxy.create(Terminator.class,
- localId,
- dtm.getLocators());
-
- return tpc;
- }
- catch (SystemException e)
- {
- if (log.isTraceEnabled())
- log.trace("Unexpected exception: ", e);
- throw new UnexpectedException("Unexpected " + e, e);
- }
- catch (NotSupportedException e)
- {
- if (log.isTraceEnabled())
- log.trace("Unexpected exception: ", e);
- throw new UnexpectedException("Unexpected " + e, e);
- }
- }
-
- public TxPropagationContext recreate(long targetId,
- TxPropagationContext tpc)
- throws RemoteException
- {
- log.trace("TransactionFactory.recreate");
-
- if (tpc == null)
- throw new IllegalArgumentException(
- "recreate: TxPropagationContext parameter cannot be null");
-
- TxManager tm = (TxManager) TMUtil.getTransactionManager();
- TransactionImpl tx = tm.importExternalTransaction(tpc.formatId,
- tpc.globalId,
- tpc.coordinator,
- tpc.timeout * 1000);
-
- // Create remote proxy to the local Coordinator
- Coordinator subCoordinator =
- (Coordinator) RemoteProxy.create(Coordinator.class,
- tx.getLocalIdValue(),
- dtm.getLocators());
-
- // Return TPC with the interposed subCoordinator and a null Terminator
- return new TxPropagationContext(tpc.formatId,
- tpc.globalId,
- tpc.timeout,
- subCoordinator,
- null);
- }
-
- // ICoordinator methods ------------------------------------------
-
- public Status getStatus(long targetId)
- throws RemoteException
- {
- if (log.isTraceEnabled())
- log.trace("Coordinator.getStatus, targetId=" +
- Long.toHexString(targetId));
-
- LocalId localId = new LocalId(targetId);
- Transaction tx = TMUtil.getTransaction(localId);
-
- if (tx == null)
- {
- log.trace("RemoteException in getStatus: transaction not found");
- // Not sure if here it would be better to return StatusNoTransaction
- // instead of throwing NoSuchObjectException... (Francisco)
- throw new NoSuchObjectException("No transaction.");
- // return Status.NO_TRANSACTION; // ?
- }
-
- int status;
-
- try
- {
- status = tx.getStatus();
- }
- catch (SystemException e)
- {
- if (log.isTraceEnabled())
- log.trace("Unexpected exception: ", e);
- throw new UnexpectedException("Unexpected " + e, e);
- }
- return javaxToJBoss(status);
- }
-
- public boolean isSameTransaction(long targetId, Coordinator c)
- throws RemoteException
- {
- if (log.isTraceEnabled())
- log.trace("Coordinator.isSameTransaction, targetId=" +
- Long.toHexString(targetId));
- return getTransactionId(targetId).equals(c.getTransactionId());
- }
-
- public int hashTransaction(long targetId)
- throws RemoteException
- {
- if (log.isTraceEnabled())
- log.trace("Coordinator.hashTransaction, targetId=" +
- Long.toHexString(targetId));
- return getTransactionId(targetId).hashCode();
- }
-
- public RecoveryCoordinator registerResource(long targetId, Resource r)
- throws RemoteException,
- TransactionInactiveException
- {
- if (log.isTraceEnabled())
- log.trace("Coordinator.registerResource, targetId=" +
- Long.toHexString(targetId));
-
- LocalId localId = new LocalId(targetId);
- TransactionImpl tx = (TransactionImpl)TMUtil.getTransaction(localId);
-
- if (tx == null)
- {
- log.trace("RemoteException in registerResource: " +
- "transaction not found");
- throw new NoSuchObjectException("No transaction.");
- }
-
- try
- {
- tx.enlistRemoteResource(r);
- }
- catch (RollbackException e)
- {
- if (log.isTraceEnabled())
- log.trace("Exception: ", e);
- TransactionRolledbackException ex =
- new TransactionRolledbackException(e.toString());
- ex.detail = e;
- throw ex;
- }
- catch (IllegalStateException e)
- {
- if (log.isTraceEnabled())
- log.trace("Exception: ", e);
- throw new TransactionInactiveException(e);
- }
-
- // Create remote proxies to the RecoveryCoordinator
- RecoveryCoordinator rc =
- (RecoveryCoordinator) RemoteProxy.create(RecoveryCoordinator.class,
- targetId,
- dtm.getLocators());
- return rc;
- }
-
- public void registerSynchronization(long targetId,
- final Synchronization sync)
- throws RemoteException,
- TransactionInactiveException
- {
- if (log.isTraceEnabled())
- log.trace("Coordinator.registerSynchronization, targetId=" +
- Long.toHexString(targetId));
-
- LocalId localId = new LocalId(targetId);
- Transaction tx = TMUtil.getTransaction(localId);
-
- if (tx == null)
- {
- log.trace("RemoteException in registerSynchronization: " +
- "transaction not found");
- throw new NoSuchObjectException("No transaction.");
- }
-
- try
- {
- tx.registerSynchronization(
- new javax.transaction.Synchronization()
- {
- public void beforeCompletion()
- {
- try
- {
- sync.beforeCompletion();
- }
- catch (RemoteException e)
- {
- if (log.isTraceEnabled())
- log.trace("RemoteException in beforeCompletion: " + e);
- }
- }
- public void afterCompletion(int status)
- {
- try
- {
- sync.afterCompletion(javaxToJBoss(status));
- }
- catch (RemoteException e)
- {
- if (log.isTraceEnabled())
- log.trace("RemoteException in afterCompletion: " + e);
- }
- }
- });
- }
- catch (RollbackException e)
- {
- if (log.isTraceEnabled())
- log.trace("Exception: ", e);
- TransactionRolledbackException ex =
- new TransactionRolledbackException(e.toString());
- ex.detail = e;
- throw ex;
- }
- catch (IllegalStateException e)
- {
- if (log.isTraceEnabled())
- log.trace("Unexpected exception: ", e);
- throw new TransactionInactiveException(e);
- }
- catch (SystemException e)
- {
- if (log.isTraceEnabled())
- log.trace("Unexpected exception: ", e);
- throw new UnexpectedException("Unexpected " + e, e);
- }
- }
-
- public void rollbackOnly(long targetId)
- throws RemoteException,
- TransactionInactiveException
- {
- if (log.isTraceEnabled())
- log.trace("Coordinator.rollbackOnly, targetId=" +
- Long.toHexString(targetId));
-
- LocalId localId = new LocalId(targetId);
- Transaction tx = TMUtil.getTransaction(localId);
-
- if (tx == null)
- {
- log.trace("RemoteException in rollbackOnly: transaction not found");
- throw new NoSuchObjectException("No transaction.");
- }
-
- try
- {
- tx.setRollbackOnly();
- }
- catch (IllegalStateException e)
- {
- if (log.isTraceEnabled())
- log.trace("Unexpected exception: ", e);
- throw new TransactionInactiveException(e);
- }
- catch (SystemException e)
- {
- if (log.isTraceEnabled())
- log.trace("Unexpected exception: ", e);
- throw new UnexpectedException("Unexpected " + e, e);
- }
- }
-
- public TxPropagationContext getTransactionContext(long targetId)
- throws RemoteException,
- TransactionInactiveException
- {
- if (log.isTraceEnabled())
- log.trace("Coordinator.getTransactionContext, targetId=" +
- Long.toHexString(targetId));
-
- LocalId localId = new LocalId(targetId);
- TransactionImpl tx = (TransactionImpl)TMUtil.getTransaction(localId);
-
- if (tx == null)
- {
- log.trace("RemoteException in getTransactionContext: " +
- "transaction not found");
- throw new NoSuchObjectException("No transaction.");
- }
-
- TxPropagationContext txPropagationContext = tx.getPropagationContext();
- if (txPropagationContext != null)
- return tx.getPropagationContext();
- else
- throw new TransactionInactiveException();
- }
-
- public GlobalId getTransactionId(long targetId)
- throws RemoteException
- {
- if (log.isTraceEnabled())
- log.trace("Coordinator.getTransactionId, targetId="
- + Long.toHexString(targetId));
-
- LocalId localId = new LocalId(targetId);
- TransactionImpl tx = (TransactionImpl)TMUtil.getTransaction(localId);
-
- if (tx == null)
- {
- log.trace("RemoteException in getTransactionId: " +
- "transaction not found");
- throw new NoSuchObjectException("No transaction.");
- }
-
- return tx.getGlobalId();
- }
-
- // ITerminator methods -------------------------------------------
-
- public void commit(long targetId, boolean reportHeuristics)
- throws RemoteException,
- HeuristicMixedException,
- HeuristicHazardException
- {
- if (log.isTraceEnabled())
- log.trace("Terminator.commit, targetId=" +
- Long.toHexString(targetId));
-
- LocalId localId = new LocalId(targetId);
- Transaction tx = TMUtil.getTransaction(localId);
-
- if (tx == null)
- {
- log.trace("RemoteException in commit: transaction not found");
- throw new NoSuchObjectException("No transaction.");
- }
-
- try
- {
- tx.commit();
- }
- catch (RollbackException e)
- {
- if (log.isTraceEnabled())
- log.trace("Exception: ", e);
- TransactionRolledbackException ex =
- new TransactionRolledbackException(e.toString());
- ex.detail = e;
- throw ex;
- }
- catch (HeuristicMixedException e)
- {
- if (log.isTraceEnabled())
- log.trace("Exception: ", e);
- if (reportHeuristics)
- {
- HeuristicMixedException ex = new HeuristicMixedException();
- ex.initCause(e);
- throw ex;
- }
- }
- catch (HeuristicRollbackException e)
- {
- if (log.isTraceEnabled())
- log.trace("Exception: ", e);
- TransactionRolledbackException ex =
- new TransactionRolledbackException(e.toString());
- ex.detail = e;
- throw ex;
- }
- catch (SecurityException e)
- {
- if (log.isTraceEnabled())
- log.trace("Unexpected exception: ", e);
- throw new AccessException(e.toString(), e);
- }
- catch (IllegalStateException e)
- {
- if (log.isTraceEnabled())
- log.trace("Unexpected exception: ", e);
- throw new RemoteException(e.toString(), e);
- }
- catch (SystemException e)
- {
- if (log.isTraceEnabled())
- log.trace("Unexpected exception: ", e);
- throw new UnexpectedException(e.toString(), e);
- }
- }
-
- public void rollback(long targetId)
- throws RemoteException
- {
- if (log.isTraceEnabled())
- log.trace("Terminator.rollback, targetId=" +
- Long.toHexString(targetId));
-
- LocalId localId = new LocalId(targetId);
- Transaction tx = TMUtil.getTransaction(localId);
-
- if (tx == null)
- {
- log.trace("RemoteException in rollback: transaction not found");
- throw new NoSuchObjectException("No transaction.");
- }
-
- try
- {
- tx.rollback();
- }
- catch (IllegalStateException e)
- {
- if (log.isTraceEnabled())
- log.trace("Unexpected exception: ", e);
- throw new RemoteException(e.toString(), e);
- }
- catch (SecurityException e)
- {
- if (log.isTraceEnabled())
- log.trace("Unexpected exception: ", e);
- throw new AccessException(e.toString(), e);
- }
- catch (SystemException e)
- {
- if (log.isTraceEnabled())
- log.trace("Unexpected exception: ", e);
- throw new UnexpectedException(e.toString(), e);
- }
- }
-
- // IResource methods ------------------------------------------
-
- public Vote prepare(long targetId)
- throws RemoteException,
- HeuristicMixedException,
- HeuristicHazardException
- {
- if (log.isTraceEnabled())
- log.trace("Resource.prepare, targetId=" + Long.toHexString(targetId));
-
- LocalId localId = new LocalId(targetId);
- TransactionImpl tx = (TransactionImpl)TMUtil.getTransaction(localId);
-
- if (tx == null)
- {
- log.trace("RemoteException in prepare: transaction not found");
- throw new NoSuchObjectException("No transaction.");
- }
-
- TransactionManager tm = TMUtil.getTransactionManager();
- try
- {
- tm.resume(tx);
- int vote = tx.prepare(null);
-
- if (vote == XAResource.XA_OK)
- return Vote.COMMIT;
- else // (vote == XAResource.XA_RDONLY)
- return Vote.READONLY;
- }
- catch (RollbackException e)
- {
- return Vote.ROLLBACK;
- }
- catch (javax.transaction.HeuristicMixedException e)
- {
- if (log.isTraceEnabled())
- log.trace("Exception: ", e);
- HeuristicMixedException ex = new HeuristicMixedException();
- ex.initCause(e);
- throw ex;
- }
- catch (javax.transaction.HeuristicRollbackException e)
- {
- if (log.isTraceEnabled())
- log.trace("Exception: ", e);
- HeuristicHazardException ex = new HeuristicHazardException();
- ex.initCause(e);
- throw ex;
- }
- catch (Exception e)
- {
- if (log.isTraceEnabled())
- log.trace("Unexpected exception: ", e);
- throw new UnexpectedException(e.toString(), e);
- }
- finally
- {
- try
- {
- tm.suspend();
- }
- catch (SystemException e)
- {
- if (log.isTraceEnabled())
- log.trace("Unexpected exception: ", e);
- throw new UnexpectedException(e.toString(), e);
- }
- }
- }
-
- public void rollbackResource(long targetId)
- throws RemoteException,
- HeuristicCommitException,
- HeuristicMixedException,
- HeuristicHazardException
- {
- if (log.isTraceEnabled())
- log.trace("Resource.rollback, targetId=" +
- Long.toHexString(targetId));
-
- LocalId localId = new LocalId(targetId);
- TransactionImpl tx = (TransactionImpl)TMUtil.getTransaction(localId);
-
- if (tx == null)
- {
- log.trace("RemoteException in rollback: transaction not found");
- throw new NoSuchObjectException("No transaction.");
- }
-
- try
- {
- tx.rollbackBranch();
- }
- catch (IllegalStateException e)
- {
- if (log.isTraceEnabled())
- log.trace("Unexpected exception: ", e);
- throw new RemoteException(e.toString(), e);
- }
- }
-
- public void commit(long targetId)
- throws RemoteException,
- TransactionNotPreparedException,
- HeuristicRollbackException,
- HeuristicMixedException,
- HeuristicHazardException
- {
- if (log.isTraceEnabled())
- log.trace("Resource.commit, targetId=" + Long.toHexString(targetId));
-
- LocalId localId = new LocalId(targetId);
- TransactionImpl tx = (TransactionImpl)TMUtil.getTransaction(localId);
-
- if (tx == null)
- {
- log.trace("RemoteException in commit: transaction not found");
- throw new NoSuchObjectException("No transaction.");
- }
-
- try
- {
- tx.commit(false);
- }
- catch (IllegalStateException e)
- {
- if (log.isTraceEnabled())
- log.trace("Exception: ", e);
- TransactionNotPreparedException ex =
- new TransactionNotPreparedException();
- ex.initCause(e);
- throw ex;
- }
- catch (RollbackException e)
- {
- if (log.isTraceEnabled())
- log.trace("Exception: ", e);
- TransactionRolledbackException ex =
- new TransactionRolledbackException(e.toString());
- ex.detail = e;
- throw ex;
- }
- catch (javax.transaction.HeuristicMixedException e)
- {
- if (log.isTraceEnabled())
- log.trace("Exception: ", e);
- HeuristicMixedException ex = new HeuristicMixedException();
- ex.initCause(e);
- throw ex;
- }
- catch (javax.transaction.HeuristicRollbackException e)
- {
- if (log.isTraceEnabled())
- log.trace("Exception: ", e);
- HeuristicRollbackException ex = new HeuristicRollbackException();
- ex.initCause(e);
- throw ex;
- }
- catch (SystemException e)
- {
- if (log.isTraceEnabled())
- log.trace("Unexpected exception: ", e);
- throw new UnexpectedException(e.toString(), e);
- }
- }
-
- public void commitOnePhase(long targetId)
- throws RemoteException,
- HeuristicHazardException
- {
- if (log.isTraceEnabled())
- log.trace("Resource.commitOnePhase, targetId=" +
- Long.toHexString(targetId));
-
- LocalId localId = new LocalId(targetId);
- TransactionImpl tx = (TransactionImpl)TMUtil.getTransaction(localId);
-
- if (tx == null)
- {
- log.trace("RemoteException in commit: transaction not found");
- throw new NoSuchObjectException("No transaction.");
- }
-
- try
- {
- tx.commit(true);
- }
- catch (RollbackException e)
- {
- if (log.isTraceEnabled())
- log.trace("Exception: ", e);
- TransactionRolledbackException ex =
- new TransactionRolledbackException(e.toString());
- ex.detail = e;
- throw ex;
- }
- catch (javax.transaction.HeuristicMixedException e)
- {
- if (log.isTraceEnabled())
- log.trace("Exception: ", e);
- throw new UnexpectedException(e.toString(), e);
- }
- catch (javax.transaction.HeuristicRollbackException e)
- {
- if (log.isTraceEnabled())
- log.trace("Exception: ", e);
- throw new UnexpectedException(e.toString(), e);
- }
- catch (SystemException e)
- {
- if (log.isTraceEnabled())
- log.trace("Unexpected exception: ", e);
- throw new UnexpectedException(e.toString(), e);
- }
- }
-
- public void forget(long targetId)
- throws RemoteException
- {
- if (log.isTraceEnabled())
- log.trace("Resource.forget, targetId=" + Long.toHexString(targetId));
-
- LocalId localId = new LocalId(targetId);
- TransactionImpl tx = (TransactionImpl)TMUtil.getTransaction(localId);
-
- if (tx == null)
- {
- log.trace("RemoteException in forget: transaction not found");
- throw new NoSuchObjectException("No transaction.");
- }
-
- tx.forget();
- }
-
- // IRecoveryCoordinator method -----------------------------------
-
- public Status replayCompletion(long targetId, final Resource r)
- throws RemoteException,
- TransactionNotPreparedException
- {
- if (log.isTraceEnabled())
- log.trace("RecoveryCoordinator.replayCompletion, targetId=" +
- Long.toHexString(targetId));
-
- TxManager tm = (TxManager) TMUtil.getTransactionManager();
- if (tm.isRecoveryPending())
- {
- if (log.isTraceEnabled())
- log.trace("RecoveryCoordinator.replayCompletion called on" +
- " targetId=" + Long.toHexString(targetId) +
- " before recovery is complete.\n" +
- " Throwing RemoteException.");
- throw new RemoteException("Transaction manager not ready.");
- }
-
- LocalId localId = new LocalId(targetId);
- TransactionImpl tx = (TransactionImpl)TMUtil.getTransaction(localId);
-
- if (tx == null)
- {
- log.trace("RemoteException in replayCompletion: " +
- "transaction not found");
- throw new NoSuchObjectException("No transaction.");
- }
-
- int status = tx.replayCompletion(r);
-
- if (status == javax.transaction.Status.STATUS_MARKED_ROLLBACK ||
- status == javax.transaction.Status.STATUS_NO_TRANSACTION ||
- status == javax.transaction.Status.STATUS_ROLLEDBACK ||
- status == javax.transaction.Status.STATUS_ROLLING_BACK)
- {
- Runnable runnable = new Runnable()
- {
- public void run()
- {
- try
- {
- r.rollback();
- }
- catch (Exception ignore)
- {
- // We can ignore this exception. If the resource didn't get
- // the rollback then it will eventually call replayCompletion
- // again.
- if (log.isTraceEnabled())
- log.trace("Ignoring exception in remote resource rollback",
- ignore);
- }
- }
- };
- Thread t = new Thread(runnable, "resourceRollbackThread");
-
- t.start();
- }
- return javaxToJBoss(status);
- }
-
- // TODO: This class does not need to implement ISynchronization
- // ISynchronization methods --------------------------------------
-
- public void beforeCompletion(long targetId)
- {
- // TODO: remove beforeCompletion
- if (log.isTraceEnabled())
- log.trace("Synchronization.beforeCompletion, targetId=" +
- Long.toHexString(targetId));
- }
-
- public void afterCompletion(long targetId)
- {
- // TODO: remove afterCompletion
- if (log.isTraceEnabled())
- log.trace("Synchronization.afterCompletion, targetId=" +
- Long.toHexString(targetId));
- }
-
- // CoordinatorFactory implementation -----------------------------
-
- /**
- * Creates a reference for the DTM object with the given interface and
- * <code>localId</code>.
- * @see org.jboss.tm.ProxyFactory#create(java.lang.Class, long)
- */
- public Coordinator createCoordinator(long localId)
- {
- return (Coordinator) RemoteProxy.create(Coordinator.class,
- localId,
- dtm.getLocators());
- }
-
- // ResourceFactory implementation --------------------------------
-
- /**
- * Creates a reference for the DTM resource with the given
- * <code>localId</code>.
- * @see org.jboss.tm.ResourceFactory#create(long)
- */
- public Resource createResource(long localId)
- {
- return (Resource) RemoteProxy.create(Resource.class,
- localId,
- dtm.getLocators());
- }
-
- // StringRemoteRefConverter implementation -----------------------
-
- /**
- * Converts a stringfied reference to a remote resource back to a remote
- * reference.
- *
- * @param strResource a stringfied reference to a remote resource
- * @return a remote reference to the resource.
- */
- public Resource stringToResource(String strResource)
- {
- try
- {
- return (Resource) RemoteProxy.fromString(strResource);
- }
- catch (Exception e)
- {
- throw new RuntimeException(e);
- }
- }
-
- /**
- * Converts a stringfied reference to a remote recovery coordinator back
- * to a remote reference.
- *
- * @param strRecCoordinator a stringfied reference to a remote recovery
- * coordinator
- * @return a remote reference to the recovery coordinator.
- */
- public RecoveryCoordinator stringToRecoveryCoordinator(
- String strRecCoordinator)
- {
- try
- {
- return (RecoveryCoordinator) RemoteProxy.fromString(strRecCoordinator);
- }
- catch (Exception e)
- {
- throw new RuntimeException(e);
- }
- }
-
- /**
- * Takes a remote reference to a resource and converts it to a string.
- *
- * @param res a remote reference to a resource
- * @return a string that represents the remote resource.
- */
- public String resourceToString(Resource res)
- {
- return RemoteProxy.toString((Proxy)res);
- }
-
- /**
- * Takes a remote reference to recovery coordinator and converts it to a
- * string.
- *
- * @param recoveryCoord a remote reference to a recovery coordinator
- * @return a string that represents the remote recovery coordinator.
- */
- public String recoveryCoordinatorToString(RecoveryCoordinator recoveryCoord)
- {
- return RemoteProxy.toString((Proxy)recoveryCoord);
- }
-
- // Private -------------------------------------------------------
-
- private static Status javaxToJBoss(int status)
- {
- return Status.fromInteger(status);
- }
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/remoting/server/DistributedTransactionManager.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/remoting/server/DistributedTransactionManager.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/remoting/server/DistributedTransactionManager.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,204 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.remoting.server;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import javax.management.ObjectName;
-import javax.naming.Context;
-import javax.naming.InitialContext;
-
-import javax.transaction.TransactionManager;
-
-import org.jboss.remoting.InvokerLocator;
-import org.jboss.system.ServiceMBeanSupport;
-import org.jboss.tm.TxManager;
-import org.jboss.tm.TMUtil;
-import org.jboss.tm.remoting.RemoteProxy;
-import org.jboss.tm.remoting.client.ClientUserTransaction;
-import org.jboss.tm.remoting.interfaces.TransactionFactory;
-
-/**
- * Service MBean that implements the distributed transaction manager.
- *
- * @author <a href="mailto:reverbel at ime.usp.br">Francisco Reverbel</a>
- * @version $Revision$
- */
-public class DistributedTransactionManager extends ServiceMBeanSupport
- implements DistributedTransactionManagerMBean
-{
- // Constants -----------------------------------------------------
-
- public static final String SUBSYSTEM = "DTM";
-
- private static final String[] addInvocationHandlerSignature =
- new String[] {
- "java.lang.String",
- "org.jboss.remoting.ServerInvocationHandler"
- };
-
- private static final String[] removeInvocationHandlerSignature =
- new String[] { "java.lang.String" };
-
- private static final Object[] removeInvocationHandlerParams =
- new Object[] { SUBSYSTEM };
-
- public static final String USER_TRANSACTION_JNDI_NAME = "UserTransaction";
-
- // Attributes ----------------------------------------------------
-
- private List connectors;
- private InvokerLocator[] locators;
- private String[] locatorURIs;
- private boolean interpositionEnabled;
-
- // ServiceMBeanSupport overrides ---------------------------------
-
- protected void startService()
- throws Exception
- {
- DTMServant dtmServant = new DTMServant(this);
- List locatorList = new ArrayList();
- List locatorURIList = new ArrayList();
- Iterator i = connectors.iterator();
-
- while (i.hasNext())
- {
- // Add DTM invocation handler to connector
- ObjectName objectName = (ObjectName) i.next();
- getServer().invoke(objectName,
- "addInvocationHandler",
- new Object[] {SUBSYSTEM,
- new DTMInvocationHandler(dtmServant)},
- addInvocationHandlerSignature);
- getLog().debug("Added DTM invocation handler to connector " +
- objectName);
-
- // Get the connector's invoker locator and locator URI
- InvokerLocator locator =
- (InvokerLocator) getServer().getAttribute(objectName, "Locator");
- locatorList.add(locator);
- String locatorURI = locator.getLocatorURI();
- locatorURIList.add(locatorURI);
- }
- locators = (InvokerLocator[]) locatorList.toArray(new InvokerLocator[0]);
- locatorURIs = (String[]) locatorURIList.toArray(new String[0]);
-
- // Set the TxManager's DTM CordinatorFactory and ResourceFactory.
- TransactionManager tm = TMUtil.getTransactionManager();
-
- if (tm instanceof TxManager)
- {
- TxManager txManager = (TxManager)tm;
- txManager.setDTMEnabled(true);
- txManager.setDTMCoordinatorFactory(dtmServant);
- txManager.setDTMResourceFactory(dtmServant);
- txManager.setDTMStringRemoteRefConverter(dtmServant);
- txManager.setInterpositionEnabled(interpositionEnabled);
- }
-
- // Bind the DTM TransactionFactory proxy into JNDI
- Context ctx = new InitialContext();
- TransactionFactory transactionFactory =
- (TransactionFactory) RemoteProxy.create(TransactionFactory.class,
- 0,
- locators);
- ctx.bind(ClientUserTransaction.TX_FACTORY_JNDI_NAME, transactionFactory);
-
- // Bind the UserTransaction reference into JNDI
- ctx.bind(USER_TRANSACTION_JNDI_NAME,
- ClientUserTransaction.getSingleton());
- }
-
- protected void stopService()
- throws Exception
- {
- // Unset the TxManager's DTM ResourceFactory.
- TxManager tm = (TxManager)TMUtil.getTransactionManager();
- tm.setDTMResourceFactory(null);
-
- Iterator i = connectors.iterator();
-
- while (i.hasNext())
- {
- // Remove DTM invocation handler from connector
- ObjectName objectName = (ObjectName) i.next();
- getServer().invoke(objectName,
- "removeInvocationHandler",
- removeInvocationHandlerParams,
- removeInvocationHandlerSignature);
- getLog().debug("Removed DTM invocation handler from connector " +
- objectName);
- }
-
- // Unset the TxManager's DTM CordinatorFactory and ResourceFactory.
- tm.setDTMEnabled(false);
- tm.setDTMCoordinatorFactory(null);
- tm.setDTMResourceFactory(null);
-
- // Unbind the DTM TransactionFactory proxy
- // and the UserTransaction reference from JNDI
- Context ctx = new InitialContext();
- ctx.unbind(ClientUserTransaction.TX_FACTORY_JNDI_NAME);
- ctx.unbind(USER_TRANSACTION_JNDI_NAME);
- }
-
- // DistributedTransactionManagerMBean methods --------------------
-
- public List getConnectors()
- {
- return connectors;
- }
-
- public void setConnectors(List connectors)
- {
- this.connectors = connectors;
- }
-
- public InvokerLocator[] getLocators()
- {
- return locators;
- }
-
- public String[] getLocatorURIs()
- {
- return locatorURIs;
- }
-
- public boolean getInterpositionEnabled()
- {
- return interpositionEnabled;
- }
-
- public void setInterpositionEnabled(boolean newValue)
- {
- interpositionEnabled = newValue;
- if (getState() == STARTED)
- {
- TxManager tm = (TxManager)TMUtil.getTransactionManager();
- tm.setInterpositionEnabled(newValue);
- }
- }
-
-}
Deleted: trunk/transaction/src/main/org/jboss/tm/remoting/server/DistributedTransactionManagerMBean.java
===================================================================
--- trunk/transaction/src/main/org/jboss/tm/remoting/server/DistributedTransactionManagerMBean.java 2007-10-03 21:43:20 UTC (rev 65812)
+++ trunk/transaction/src/main/org/jboss/tm/remoting/server/DistributedTransactionManagerMBean.java 2007-10-03 21:45:05 UTC (rev 65813)
@@ -1,49 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, 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.tm.remoting.server;
-
-import java.util.List;
-
-import org.jboss.remoting.InvokerLocator;
-import org.jboss.system.ServiceMBean;
-
-/**
- * MBean interface exposed by the DTM.
- *
- * @author <a href="mailto:reverbel at ime.usp.br">Francisco Reverbel</a>
- * @version $Revision$
- */
-public interface DistributedTransactionManagerMBean
- extends ServiceMBean
-{
- List getConnectors();
-
- void setConnectors(List connectors);
-
- InvokerLocator[] getLocators();
-
- String[] getLocatorURIs();
-
- boolean getInterpositionEnabled();
-
- void setInterpositionEnabled(boolean newValue);
-}
More information about the jboss-cvs-commits
mailing list