📄 externaltransaction.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: ExternalTransaction.java,v 1.4 2002/12/29 11:15:55 per_nyfelt Exp $
package org.ozoneDB;
import org.ozoneDB.core.Transaction;
import javax.naming.*;
import java.io.IOException;
import java.rmi.Remote;
import java.util.Hashtable;
/**
* ExternalTransaction allows an application to explicitly manage transaction
* boundaries.<p>
*
* When programming ozone applications explicite transaction demarcation is
* needed under rare circumstances only (for example: processing of binary large
* objects - BLOBs). In fact, in most cases explicite transactions are not
* really needed while implicite transactions are cleaner and faster. So, every
* time you are going to use explicite transactions, you should ask yourself if
* an implicite transaction is maybe a better choice.<p>
*
* In case of a deadlock the ordinary behaviour of ozone is to abort one of the
* locked transactions and restart until all transactions are successfully
* commited. This is not possible when explicite transactions are used! In case
* of deadlock an exceptions is thrown and the client has to decide what to do.
* <p>
*
* Note: If an operation that runs under control of this transaction fails, the
* transaction is set to rollback only.
*
*
* @author <a href="http://www.softwarebuero.de/">SMB</a>
* @version $Revision: 1.4 $Date: 2002/12/29 11:15:55 $
*/
public final class ExternalTransaction
extends AbstractTransaction
implements Referenceable {
// Constants
/** Status of a transaction: transaction is not active. */
public final static int STATUS_NONE = 1;
/** Status of a transaction: transaction has been started. */
public final static int STATUS_ACTIVE = 2;
/** Status of a transaction: transaction is about to prepare. */
public final static int STATUS_PREPARING = 3;
/** Status of a transaction: transaction has been successfully prepared. */
public final static int STATUS_PREPARED = 4;
/** Status of a transaction: transaction is about to commit.*/
public final static int STATUS_COMMITING = 5;
/** Status of a transaction: transaction has been successfully committed. */
public final static int STATUS_COMMITED = 6;
/** Status of a transaction: transaction is about to abort. */
public final static int STATUS_ROLLINGBACK = 7;
/** Status of a transaction: transaction has been aborted. */
public final static int STATUS_ROLLEDBACK = 8;
// Fields
protected boolean rollbackOnly = false;
public ExternalTransaction( ExternalDatabase _database ) {
super( _database );
}
/**
* Start work on behalf of this transaction and associate it with the current
* thread.
*
*
* @throws TransactionException If the thread is already associated with a
* transaction.
* @throws IOException If the server is not reachable.
*/
public void begin() throws TransactionException, IOException {
database.beginTX( this );
}
/**
* Attach the caller's thread to this transaction and detach the thread
* from any former Transaction the thread may have been associated with.
*/
public void join() throws TransactionException, IOException {
if (database instanceof LocalDatabase) {
// currently the client side threads are used for server internal work;
// that is, DbLocalClient just calls the appropriate server method; but
// the server can handle only one thread per transaction, therefore
// jointTX for local connections is not allowed -> one (Command)Thread per
// DbLocalClient
throw new RuntimeException( "Operation not supported: join() on LocalDatabase's." );
}
else {
database.leaveTX( this );
database.joinTX( this );
}
}
/**
* Detach the caller's thread from this <code>Transaction</code>, but do not attach
* the thread to another <code>Transaction</code>.
*/
public void leave() throws TransactionException, IOException {
database.leaveTX( this );
}
/**
* Prepares this transaction. This method is intended to be used by
* transactional applications that need two-phase commit.
*/
public void prepare() throws TransactionException, IOException {
if (rollbackOnly) {
database.rollbackTX( this );
throw new TransactionException( "Transaction was set to rollback only.", TransactionException.ROLLBACK );
} else {
// the server can also decide to rollback this transaction
database.prepareTX( this );
}
}
/**
* Complete this transaction. When this method completes, the thread
* becomes associated with no transaction. This method can be called by a
* non-joined thread.
*/
public void commit() throws TransactionException, IOException {
commit( true );
}
/**
* Complete this transaction. When this method completes, the thread
* becomes associated with no transaction. This method is intended to be
* used by transactional applications that need two-phase commit.
*/
public void commit( boolean onePhase ) throws TransactionException, IOException {
if (rollbackOnly) {
database.rollbackTX( this );
throw new TransactionException( "Transaction was set to rollback only.", TransactionException.ROLLBACK );
} else {
// the server can also decide to rollback this transaction
database.commitTX( this, onePhase );
}
}
/**
* Checkpoint this transaction. This method can also be called by a
* non-joined thread.
*/
public void checkpoint() throws TransactionException, IOException {
database.checkpointTX( this );
}
/**
* Rollback the transaction associated with the current thread. When this
* method completes, the thread becomes associated with no transaction.
* Calling this method when the transaction is not opened doe not throw
* an exception.
* <p>
* This method can be called by any threads.
*/
public void rollback() throws TransactionException, IOException {
database.rollbackTX( this );
}
/**
* Modify the transaction associated with the current thread such that the
* only possible outcome of the transaction is to roll back the transaction.
*/
public synchronized void setRollbackOnly() throws TransactionException, IOException {
rollbackOnly = true;
}
/**
* Obtain the status of the transaction associated with the current thread.
*/
public int getStatus() throws TransactionException, IOException {
int internal = database.getStatusTX( this );
// explicitely map this to avoid conflicts when codes are changed in
// of the two classes
switch (internal) {
case Transaction.STATUS_NONE:
return STATUS_NONE;
case Transaction.STATUS_STARTED:
return STATUS_ACTIVE;
case Transaction.STATUS_PREPARING:
return STATUS_PREPARING;
case Transaction.STATUS_PREPARED:
return STATUS_PREPARED;
case Transaction.STATUS_COMMITING:
return STATUS_COMMITING;
case Transaction.STATUS_COMMITED:
return STATUS_COMMITED;
case Transaction.STATUS_ABORTING:
return STATUS_ROLLINGBACK;
case Transaction.STATUS_ABORTED:
return STATUS_ROLLEDBACK;
default:
throw new RuntimeException( "Unknown internal transaction status." );
}
}
/**
* Modify the value of the timeout value that is associated with the
* transactions started by the current thread with the begin method.
*
* If an application has not called this method, the transaction service
* uses some default value for the transaction timeout.
*
*
* @param seconds The value of the timeout in seconds. If the value is zero,
* the transaction service restores the default value
*/
public void setTransactionTimeout( int seconds ) throws TransactionException, IOException {
throw new RuntimeException( "setTransactionTimeout() is not yet implemented." );
}
// JNDI stuff *****************************************
/**
* Retrieves the JNDI Reference of this object.
* @return The non-null Reference of this object.
*/
public Reference getReference() throws NamingException {
throw new RuntimeException( "getReference() is not yet implemented." );
// Reference ref;
// Package pkg;
//
// // we use same object as factory.
// ref = new Reference (getClass().getName(), getClass().getName(), null);
//
// // No properties, the entire transaction manager is static.
// pkg = ExternalTransaction.class.getPackage();
// if (pkg != null) {
// ref.add ( new StringRefAddr( "title", pkg.getImplementationTitle() ) );
// ref.add ( new StringRefAddr( "vendor", pkg.getImplementationVendor() ) );
// ref.add ( new StringRefAddr( "version", pkg.getImplementationVersion() ) );
// }
// return ref;
}
public Object getObjectInstance( Object refObj, Name name, Context nameCtx, Hashtable env ) {
// Can only reconstruct from a reference.
if (refObj instanceof Reference) {
return this;
} else if (refObj instanceof Remote) {
return refObj;
} else {
return null;
}
}
public static ExternalTransaction getInstance() {
throw new RuntimeException( "ExternalTransaction.getInstance() not implemented yet." );
// return new ExternalTransaction (database);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -