📄 ozonexaresource.java
字号:
// You can redistribute this software and/or modify it under the terms of
// the Ozone Library License version 1 published by ozone-db.org.
//
// The original code and portions created by SMB are
// Copyright (C) 1997-@year@ by SMB GmbH. All rights reserved.
//
// $Id: OzoneXAResource.java,v 1.3 2002/09/18 06:54:18 per_nyfelt Exp $
package org.ozoneDB.xa;
import org.ozoneDB.DxLib.*;
import org.ozoneDB.ExternalDatabase;
import org.ozoneDB.TransactionException;
import javax.transaction.Status;
import javax.transaction.xa.*;
import java.io.PrintStream;
/**
* This is the XA adapter (XAResource) for an ozone database connection. It is
* created using the getXAResource method of an ExternalDatabase. It allows an
* TransactionManager to control transaction demarcation in an ozone database.
*
* @author <a href="http://www.softwarebuero.de/">SMB</a>
* @version $Revision: 1.3 $Date: 2002/09/18 06:54:18 $
*/
public class OzoneXAResource implements XAResource {
private ExternalDatabase db;
private DxHashMap xids;
private PrintStream log;
public OzoneXAResource( ExternalDatabase _db ) {
db = _db;
xids = new DxHashMap();
log = System.out;
}
public String toString() {
return "OzoneXAResource [" + db + "]";
}
protected void debug( String msg ) {
log.println( "OzoneXAResource: " + msg );
}
/**
* Start work on behalf of a transaction branch specified in xid. If TMJOIN
* is specified, the start is for joining a transaction previously seen by
* the resource manager. If TMRESUME is specified, the start is to resume a
* suspended transaction specified in the parameter xid. If neither TMJOIN
* nor TMRESUME is specified and the transaction specified by xid has
* previously been seen by the resource manager, the resource manager throws
* the XAException exception with XAER_DUPID error code.
*/
public void start( Xid xid, int flags ) throws XAException {
debug( "start(): xid:" + xid.hashCode() + ", flags:" + flags );
if (xid == null) {
throw new XAException( XAException.XAER_INVAL );
}
if (db == null) {
throw new XAException( XAException.XAER_OUTSIDE );
}
try {
switch (flags) {
case TMNOFLAGS: {
debug( "start(): TMNOFLAGS..." );
XATransaction tx = new XATransaction( db );
if (!xids.addForKey( tx, xid )) {
throw new XAException( XAException.XAER_DUPID );
}
db.beginTX( tx );
break;
}
case TMRESUME : {
debug( "start(): TMRESUME..." );
XATransaction tx = (XATransaction)xids.elementForKey( xid );
if (tx == null) {
throw new XAException( "Specified XID not found." );
}
db.joinTX( tx );
break;
}
case TMJOIN : {
debug( "start(): TMJOIN..." );
throw new RuntimeException( "Not implemented yet." );
}
default: {
debug( "start(): unknown flag..." );
// No other flags are supported in start().
throw new XAException( XAException.XAER_INVAL );
}
}
}
catch (XAException e) {
throw e;
}
catch (Exception e) {
log.println( e );
throw new XAException( XAException.XAER_RMERR );
}
}
/**
* Ends the work performed on behalf of a transaction branch. The resource
* manager disassociates the XA resource from the transaction branch
* specified and let the transaction be completed.
*
* If TMSUSPEND is specified in flags, the transaction branch is temporarily
* suspended in incomplete state. The transaction context is in suspened
* state and must be resumed via start with TMRESUME specified.
*
*
* If TMFAIL is specified, the portion of work has failed. The resource
* manager may mark the transaction as rollback-only If TMSUCCESS is
* specified, the portion of work has completed successfully.
*/
public void end( Xid xid, int flags ) throws XAException {
debug( "end(): xid:" + xid.hashCode() + ", flags:" + flags );
if (xid == null) {
throw new XAException( XAException.XAER_INVAL );
}
try {
XATransaction tx = (XATransaction)xids.elementForKey( xid );
if (xid == null) {
throw new XAException( XAException.XAER_NOTA );
}
switch (flags) {
case TMSUCCESS: {
debug( "end(): TMSUCCESS..." );
db.leaveTX( tx );
break;
}
case TMFAIL: {
debug( "end(): TMFAIL..." );
db.rollbackTX( tx );
break;
}
case TMSUSPEND: {
debug( "end(): TMSUSPEND..." );
db.leaveTX( tx );
break;
}
default: {
debug( "end(): unknown flag..." );
// No other flags are supported in end().
throw new XAException( XAException.XAER_INVAL );
}
}
}
catch (XAException e) {
throw e;
}
catch (Exception e) {
log.println( e );
throw new XAException( XAException.XAER_RMERR );
}
}
/**
* Ask the resource manager to prepare for a transaction commit of the
* transaction specified in xid.
*/
public int prepare( Xid xid ) throws XAException {
debug( "prepare(): xid:" + xid.hashCode() );
if (xid == null) {
throw new XAException( XAException.XAER_INVAL );
}
try {
XATransaction tx = (XATransaction)xids.elementForKey( xid );
if (xid == null) {
throw new XAException( XAException.XAER_NOTA );
}
db.prepareTX( tx );
return XA_OK;
}
catch (XAException e) {
throw e;
}
catch (TransactionException e) {
log.println( e );
throw new XAException( XAException.XA_RBROLLBACK );
}
catch (Exception e) {
log.println( e );
throw new XAException( XAException.XAER_RMERR );
}
}
/**
* Commit the global transaction specified by xid.
*/
public void commit( Xid xid, boolean onePhase ) throws XAException {
debug( "commit(): xid:" + xid.hashCode() + ", onePhase:" + onePhase );
if (xid == null) {
throw new XAException( XAException.XAER_INVAL );
}
try {
XATransaction tx = (XATransaction)xids.elementForKey( xid );
if (xid == null) {
throw new XAException( XAException.XAER_NOTA );
}
db.commitTX( tx, onePhase );
}
catch (XAException e) {
throw e;
}
catch (TransactionException e) {
log.println( e );
throw new XAException( XAException.XA_RBROLLBACK );
}
catch (Exception e) {
log.println( e );
throw new XAException( XAException.XAER_RMERR );
}
}
/**
* Inform the resource manager to roll back work done on behalf of a
* transaction branch.
*/
public void rollback( Xid xid ) throws XAException {
debug( "rollback(): xid:" + xid.hashCode() );
if (xid == null) {
throw new XAException( XAException.XAER_INVAL );
}
try {
XATransaction tx = (XATransaction)xids.elementForKey( xid );
if (xid == null) {
throw new XAException( XAException.XAER_NOTA );
}
db.rollbackTX( tx );
}
catch (XAException e) {
throw e;
}
catch (Exception e) {
log.println( e );
throw new XAException( XAException.XAER_RMERR );
}
}
/**
* Tell the resource manager to forget about a heuristically completed
* transaction branch.
*/
public void forget( Xid xid ) throws XAException {
debug( "forget(): xid:" + xid.hashCode() );
xids.removeForKey( xid );
}
/**
* Set the current transaction timeout value for this XAResource instance.
* Once set, this timeout value is effective until setTransactionTimeout is
* invoked again with a different value. To reset the timeout value to the
* default value used by the resource manager, set the value to zero. If the
* timeout operation is performed successfully, the method returns true;
* otherwise false. If a resource manager does not support transaction
* timeout value to be set explicitly, this method returns false.
*/
public boolean setTransactionTimeout( int seconds ) throws XAException {
debug( "setTransactionTimeout(): seconds:" + seconds );
return false;
}
/**
* Obtain the current transaction timeout value set for this XAResource
* instance. If XAResource.setTransactionTimeout was not use prior to
* invoking this method, the return value is the default timeout set for the
* resource manager; otherwise, the value used in the previous
* setTransactionTimeout call is returned.
*/
public int getTransactionTimeout() throws XAException {
debug( "getTransactionTimeout():" );
return -1;
}
/**
* This method is called to determine if the resource manager instance
* represented by the target object is the same as the resouce manager
* instance represented by the parameter xares.
*/
public boolean isSameRM( XAResource xares ) throws XAException {
debug( "isSameRM(): xares:" + xares );
if (xares != null && xares instanceof OzoneXAResource) {
return db == ((OzoneXAResource)xares).db;
} else {
return false;
}
}
/**
* Obtain a list of prepared transaction branches from a resource manager.
* The transaction manager calls this method during recovery to obtain the
* list of transaction branches that are currently in prepared or
* heuristically completed states.
*/
public Xid[] recover( int flag ) throws XAException {
debug( "recover(): flags:" + flag );
try {
DxArrayBag result = new DxArrayBag();
DxIterator it = xids.iterator();
while (it.next() != null) {
XATransaction tx = (XATransaction)it.object();
if (db.getStatusTX( tx ) == Status.STATUS_PREPARED) {
result.add( tx );
}
}
return (Xid[])result.toArray();
}
catch (Exception e) {
throw new XAException( e.toString() );
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -