org.firebirdsql.jdbc.InternalTransactionCoordinator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jaybird Show documentation
Show all versions of jaybird Show documentation
JDBC Driver for the Firebird RDBMS
package org.firebirdsql.jdbc;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import javax.resource.ResourceException;
import org.firebirdsql.jca.FirebirdLocalTransaction;
/**
* Transaction coordinator for the {@link org.firebirdsql.jdbc.FBConnection} class.
*/
public class InternalTransactionCoordinator implements FBObjectListener.StatementListener, FBObjectListener.BlobListener, Synchronizable {
private AbstractTransactionCoordinator coordinator;
public InternalTransactionCoordinator() {
// empty
}
public Object getSynchronizationObject() throws SQLException {
if (coordinator instanceof AutoCommitCoordinator)
return coordinator.getConnection();
else
return new Object();
}
public InternalTransactionCoordinator(AbstractTransactionCoordinator coordinator) {
this.coordinator = coordinator;
}
public void executionStarted(AbstractStatement stmt) throws SQLException {
Object syncObject = getSynchronizationObject();
synchronized (syncObject) {
coordinator.executionStarted(stmt);
}
}
public AbstractConnection getConnection() throws SQLException {
return coordinator.getConnection();
}
public void statementClosed(AbstractStatement stmt) throws SQLException {
coordinator.statementClosed(stmt);
}
public void statementCompleted(AbstractStatement stmt) throws SQLException {
statementCompleted(stmt, true);
}
public void statementCompleted(AbstractStatement stmt, boolean success) throws SQLException {
Object syncObject = getSynchronizationObject();
synchronized (syncObject) {
coordinator.statementCompleted(stmt, success);
}
}
public void executionCompleted(FirebirdBlob blob) throws SQLException {
Object syncObject = getSynchronizationObject();
synchronized (syncObject) {
coordinator.executionCompleted(blob);
}
}
public void executionStarted(FirebirdBlob blob) throws SQLException {
Object syncObject = getSynchronizationObject();
synchronized (syncObject) {
coordinator.executionStarted(blob);
}
}
public void ensureTransaction() throws SQLException {
Object syncObject = getSynchronizationObject();
synchronized (syncObject) {
coordinator.ensureTransaction();
}
}
public void commit() throws SQLException {
Object syncObject = getSynchronizationObject();
synchronized (syncObject) {
coordinator.commit();
}
}
public void rollback() throws SQLException {
Object syncObject = getSynchronizationObject();
synchronized (syncObject) {
coordinator.rollback();
}
}
public void setCoordinator(AbstractTransactionCoordinator coordinator) throws SQLException {
Object syncObject = getSynchronizationObject();
synchronized (syncObject) {
if (this.coordinator != null) {
this.coordinator.completeStatements();
coordinator.setStatements(this.coordinator.getStatements());
}
this.coordinator = coordinator;
}
}
public abstract static class AbstractTransactionCoordinator implements FBObjectListener.StatementListener, FBObjectListener.BlobListener {
protected FirebirdLocalTransaction localTransaction;
protected AbstractConnection connection;
protected Collection statements = new ArrayList();
protected AbstractTransactionCoordinator(AbstractConnection connection, FirebirdLocalTransaction localTransaction) {
this.localTransaction = localTransaction;
this.connection = connection;
}
/**
* Get the connection which owns this coordinator.
*
* @return instance of {@link AbstractConnection}
*/
public AbstractConnection getConnection() throws SQLException {
return connection;
}
protected Collection getStatements() {
return statements;
}
protected void setStatements(Collection statements) {
this.statements.addAll(statements);
}
protected void completeStatements() throws SQLException {
SQLException resultEx = null;
// we have to loop through the array, since the
// statement.completeStatement() call causes the
// ConcurrentModificationException
Object[] statementsToComplete = statements.toArray();
for (int i = 0; i < statementsToComplete.length; i++) {
AbstractStatement statement =
(AbstractStatement)statementsToComplete[i];
try {
statement.completeStatement();
} catch(SQLException ex) {
if (resultEx == null)
resultEx = ex;
else
resultEx.setNextException(ex);
}
}
// clear the statements (usually needed only for those that
// were not removed in the statement.completeStatement() call
statements.clear();
try {
if (localTransaction.inTransaction())
localTransaction.commit();
} catch(ResourceException ex) {
throw new FBSQLException(ex);
}
if (resultEx != null)
throw resultEx;
}
public abstract void ensureTransaction() throws SQLException;
public abstract void commit() throws SQLException;
public abstract void rollback() throws SQLException;
}
public static class AutoCommitCoordinator extends AbstractTransactionCoordinator {
/**
* @param connection
* @param localTransaction
*/
public AutoCommitCoordinator(AbstractConnection connection,
FirebirdLocalTransaction localTransaction) {
super(connection, localTransaction);
}
/* (non-Javadoc)
* @see org.firebirdsql.jdbc.FBObjectListener.StatementListener#executionStarted(java.sql.Statement)
*/
public void executionStarted(AbstractStatement stmt) throws SQLException {
ArrayList tempList = new ArrayList(statements);
// complete all open statements for the connection
// (there should be only one anyway)
for (Iterator iter = tempList.iterator(); iter.hasNext();) {
AbstractStatement tempStatement = (AbstractStatement) iter.next();
// enable re-entrancy for the same statement
if (tempStatement == stmt) {
iter.remove();
continue;
}
tempStatement.completeStatement();
}
statements.removeAll(tempList);
if (statements.contains(stmt))
return;
if (!statements.contains(stmt))
statements.add(stmt);
ensureTransaction();
}
/* (non-Javadoc)
* @see org.firebirdsql.jdbc.InternalTransactionCoordinator.AbstractTransactionCoordinator#ensureTransaction()
*/
public void ensureTransaction() throws SQLException {
try {
if (!localTransaction.inTransaction())
localTransaction.begin();
} catch(ResourceException ex) {
throw new FBSQLException(ex);
}
}
/* (non-Javadoc)
* @see org.firebirdsql.jdbc.FBObjectListener.StatementListener#statementClosed(java.sql.Statement)
*/
public void statementClosed(AbstractStatement stmt) throws SQLException {
stmt.completeStatement();
connection.notifyStatementClosed(stmt);
}
public void statementCompleted(AbstractStatement stmt) throws SQLException {
statementCompleted(stmt, true);
}
/* (non-Javadoc)
* @see org.firebirdsql.jdbc.FBObjectListener.StatementListener#statementCompleted(java.sql.Statement)
*/
public void statementCompleted(AbstractStatement stmt, boolean success) throws SQLException {
statements.remove(stmt);
try {
if (!localTransaction.inTransaction())
return;
if (success)
localTransaction.commit();
else
localTransaction.rollback();
} catch(ResourceException ex) {
try {
if (localTransaction.inTransaction())
localTransaction.rollback();
} catch(ResourceException ex1) {
throw new FBSQLException(ex1);
}
throw new FBSQLException(ex);
}
}
/* (non-Javadoc)
* @see org.firebirdsql.jdbc.FBObjectListener.BlobListener#executionCompleted(org.firebirdsql.jdbc.FirebirdBlob)
*/
public void executionCompleted(FirebirdBlob blob) throws SQLException {
// do nothing, next line exists only for breakpoint
int i = 0;
}
/* (non-Javadoc)
* @see org.firebirdsql.jdbc.FBObjectListener.BlobListener#executionStarted(org.firebirdsql.jdbc.FirebirdBlob)
*/
public void executionStarted(FirebirdBlob blob) throws SQLException {
ensureTransaction();
}
/* (non-Javadoc)
* @see org.firebirdsql.jdbc.InternalTransactionCoordinator#commit()
*/
public void commit() throws SQLException {
throw new FBSQLException(
"Calling commit() in auto-commit mode is not allowed.");
}
/* (non-Javadoc)
* @see org.firebirdsql.jdbc.InternalTransactionCoordinator#rollback()
*/
public void rollback() throws SQLException {
throw new FBSQLException(
"Calling rollback() in auto-commit mode is not allowed.");
}
}
public static class LocalTransactionCoordinator extends AbstractTransactionCoordinator {
/**
* @param connection
* @param localTransaction
*/
public LocalTransactionCoordinator(AbstractConnection connection,
FirebirdLocalTransaction localTransaction) {
super(connection, localTransaction);
}
/* (non-Javadoc)
* @see org.firebirdsql.jdbc.InternalTransactionCoordinator.AbstractTransactionCoordinator#ensureTransaction()
*/
public void ensureTransaction() throws SQLException {
try {
if (!localTransaction.inTransaction())
localTransaction.begin();
} catch(ResourceException ex) {
throw new FBSQLException(ex);
}
}
/* (non-Javadoc)
* @see org.firebirdsql.jdbc.InternalTransactionCoordinator#commit()
*/
public void commit() throws SQLException {
try {
if (localTransaction.inTransaction())
localTransaction.commit();
} catch(ResourceException ex) {
throw new FBSQLException(ex);
}
}
/* (non-Javadoc)
* @see org.firebirdsql.jdbc.InternalTransactionCoordinator#rollback()
*/
public void rollback() throws SQLException {
try {
if (localTransaction.inTransaction())
localTransaction.rollback();
} catch(ResourceException ex) {
throw new FBSQLException(ex);
}
}
/* (non-Javadoc)
* @see org.firebirdsql.jdbc.FBObjectListener.StatementListener#executionStarted(java.sql.Statement)
*/
public void executionStarted(AbstractStatement stmt) throws SQLException {
ensureTransaction();
}
/* (non-Javadoc)
* @see org.firebirdsql.jdbc.FBObjectListener.StatementListener#statementClosed(java.sql.Statement)
*/
public void statementClosed(AbstractStatement stmt) throws SQLException {
stmt.completeStatement();
connection.notifyStatementClosed(stmt);
}
/* (non-Javadoc)
* @see org.firebirdsql.jdbc.FBObjectListener.StatementListener#statementCompleted(java.sql.Statement)
*/
public void statementCompleted(AbstractStatement stmt) throws SQLException {
}
public void statementCompleted(AbstractStatement stmt, boolean success) throws SQLException {
}
/* (non-Javadoc)
* @see org.firebirdsql.jdbc.FBObjectListener.BlobListener#executionCompleted(org.firebirdsql.jdbc.FirebirdBlob)
*/
public void executionCompleted(FirebirdBlob blob) throws SQLException {
// empty
}
/* (non-Javadoc)
* @see org.firebirdsql.jdbc.FBObjectListener.BlobListener#executionStarted(org.firebirdsql.jdbc.FirebirdBlob)
*/
public void executionStarted(FirebirdBlob blob) throws SQLException {
ensureTransaction();
}
}
public static class ManagedTransactionCoordinator extends LocalTransactionCoordinator {
/**
* Create instance of this class for the specified connection.
*
* @param connection connection to coordinate.
*/
public ManagedTransactionCoordinator(AbstractConnection connection) {
super(connection, null);
}
/* (non-Javadoc)
* @see org.firebirdsql.jdbc.InternalTransactionCoordinator.AbstractTransactionCoordinator#completeStatements()
*/
protected void completeStatements() throws SQLException {
SQLException resultEx = null;
// we have to loop through the array, since the
// statement.completeStatement() call causes the
// ConcurrentModificationException
Object[] statementsToComplete = statements.toArray();
for (int i = 0; i < statementsToComplete.length; i++) {
AbstractStatement statement =
(AbstractStatement)statementsToComplete[i];
try {
statement.completeStatement();
} catch(SQLException ex) {
if (resultEx == null)
resultEx = ex;
else
resultEx.setNextException(ex);
}
}
statements.clear();
}
/* (non-Javadoc)
* @see org.firebirdsql.jdbc.InternalTransactionCoordinator.AbstractTransactionCoordinator#ensureTransaction()
*/
public void ensureTransaction() throws SQLException {
// do nothing, we are in managed environment.
}
/* (non-Javadoc)
* @see org.firebirdsql.jdbc.FBObjectListener.StatementListener#executionStarted(java.sql.Statement)
*/
public void executionStarted(AbstractStatement stmt) throws SQLException {
// NO TRANSACTION MANAGEMENT HERE - empty method
}
/* (non-Javadoc)
* @see org.firebirdsql.jdbc.InternalTransactionCoordinator#commit()
*/
public void commit() throws SQLException {
// do nothing, we are in managed environment.
}
/* (non-Javadoc)
* @see org.firebirdsql.jdbc.InternalTransactionCoordinator#rollback()
*/
public void rollback() throws SQLException {
// do nothing, we are in managed environment.
}
/* (non-Javadoc)
* @see org.firebirdsql.jdbc.FBObjectListener.BlobListener#executionStarted(org.firebirdsql.jdbc.FirebirdBlob)
*/
public void executionStarted(FirebirdBlob blob) throws SQLException {
// empty
}
}
public static class MetaDataTransactionCoordinator extends AbstractTransactionCoordinator {
private InternalTransactionCoordinator tc;
public MetaDataTransactionCoordinator(InternalTransactionCoordinator tc) {
super(tc.coordinator.connection, tc.coordinator.connection.getLocalTransaction());
this.tc = tc;
}
/**
* Create coordinator for the unspecified connection.
*/
public MetaDataTransactionCoordinator() {
super(null, null);
}
/* (non-Javadoc)
* @see org.firebirdsql.jdbc.InternalTransactionCoordinator.AbstractTransactionCoordinator#ensureTransaction()
*/
public void ensureTransaction() throws SQLException {
throw new UnsupportedOperationException();
}
/* (non-Javadoc)
* @see org.firebirdsql.jdbc.InternalTransactionCoordinator#commit()
*/
public void commit() throws SQLException {
throw new UnsupportedOperationException();
}
/* (non-Javadoc)
* @see org.firebirdsql.jdbc.InternalTransactionCoordinator#rollback()
*/
public void rollback() throws SQLException {
throw new UnsupportedOperationException();
}
/* (non-Javadoc)
* @see org.firebirdsql.jdbc.FBObjectListener.StatementListener#executionStarted(java.sql.Statement)
*/
public void executionStarted(AbstractStatement stmt) throws SQLException {
if (tc == null)
return;
tc.ensureTransaction();
}
/* (non-Javadoc)
* @see org.firebirdsql.jdbc.FBObjectListener.StatementListener#statementClosed(java.sql.Statement)
*/
public void statementClosed(AbstractStatement stmt) throws SQLException {
if (tc == null)
return;
stmt.completeStatement();
tc.coordinator.connection.notifyStatementClosed(stmt);
}
public void statementCompleted(AbstractStatement stmt) throws SQLException {
statementCompleted(stmt, true);
}
/* (non-Javadoc)
* @see org.firebirdsql.jdbc.FBObjectListener.StatementListener#statementCompleted(java.sql.Statement)
*/
public void statementCompleted(AbstractStatement stmt, boolean success) throws SQLException {
if (connection == null)
return;
if (!connection.getAutoCommit())
return;
// commit in case of auto-commit mode to end the transaction that we started
try {
if (!localTransaction.inTransaction())
return;
if (success)
localTransaction.commit();
else
localTransaction.rollback();
} catch(ResourceException ex) {
try {
if (localTransaction.inTransaction())
localTransaction.rollback();
} catch(ResourceException ex1) {
throw new FBSQLException(ex1);
}
throw new FBSQLException(ex);
}
}
/* (non-Javadoc)
* @see org.firebirdsql.jdbc.FBObjectListener.BlobListener#executionCompleted(org.firebirdsql.jdbc.FirebirdBlob)
*/
public void executionCompleted(FirebirdBlob blob) throws SQLException {
}
/* (non-Javadoc)
* @see org.firebirdsql.jdbc.FBObjectListener.BlobListener#executionStarted(org.firebirdsql.jdbc.FirebirdBlob)
*/
public void executionStarted(FirebirdBlob blob) throws SQLException {
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy