[Mulgara-svn] r1057 - branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver
ronald at mulgara.org
ronald at mulgara.org
Mon Jul 7 12:54:01 UTC 2008
Author: ronald
Date: 2008-07-07 05:53:59 -0700 (Mon, 07 Jul 2008)
New Revision: 1057
Modified:
branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/Database.java
branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/DatabaseSession.java
branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/LocalJRDFDatabaseSession.java
branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/MulgaraExternalTransactionFactory.java
branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/MulgaraInternalTransactionFactory.java
branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/MulgaraTransactionFactory.java
branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/MulgaraTransactionManager.java
branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/MulgaraXAResourceContext.java
Log:
Changed scope of transaction factories to be per-session because all operations
are session-scoped anyway. This avoids the need to keep multiple maps in order
to look up the per-session information and avoids the need to pass the session
to all methods. Furthermore, with upcoming changes that rework the timeout
handling we can then completly eliminate the mutexes.
Modified: branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/Database.java
===================================================================
--- branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/Database.java 2008-07-07 06:38:28 UTC (rev 1056)
+++ branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/Database.java 2008-07-07 12:53:59 UTC (rev 1057)
@@ -237,10 +237,7 @@
private final URI temporaryModelTypeURI;
/**
- * Factory for the {@link #transactionManager}.
- *
- * This only reason we hold a reference to this is so that it can be closed
- * when the database shuts down.
+ * Factory for internal jta TransactionManager's.
*/
private final TransactionManagerFactory transactionManagerFactory;
@@ -513,7 +510,7 @@
assert this.contentHandlers != null;
// FIXME: Migrate this code inside StringPoolSession. Pass config to StringPoolSession.
- this.transactionManager = new MulgaraTransactionManager(transactionManagerFactory);
+ this.transactionManager = new MulgaraTransactionManager();
this.defaultTransactionTimeout = transactionTimeout * 1000L;
this.defaultIdleTimeout = idleTimeout * 1000L;
@@ -679,6 +676,7 @@
DatabaseSession session = new DatabaseSession(
transactionManager,
+ transactionManagerFactory,
unmodifiableSecurityAdapterList,
unmodifiableSymbolicTransformationList,
spSessionFactory,
@@ -892,6 +890,7 @@
try {
return new DatabaseSession(
transactionManager,
+ transactionManagerFactory,
unmodifiableSecurityAdapterList,
unmodifiableSymbolicTransformationList,
spSessionFactory,
@@ -922,6 +921,7 @@
try {
return new LocalJRDFDatabaseSession(
transactionManager,
+ transactionManagerFactory,
unmodifiableSecurityAdapterList,
unmodifiableSymbolicTransformationList,
jrdfSessionFactory,
@@ -1146,6 +1146,7 @@
try {
return new DatabaseSession(
transactionManager,
+ transactionManagerFactory,
Collections.singletonList(
(SecurityAdapter)new SystemModelSecurityAdapter(metadata.getSystemModelNode())
),
@@ -1176,6 +1177,7 @@
try {
return new LocalJRDFDatabaseSession(
transactionManager,
+ transactionManagerFactory,
Collections.singletonList(
new SystemModelSecurityAdapter(metadata.getSystemModelNode())
),
Modified: branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/DatabaseSession.java
===================================================================
--- branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/DatabaseSession.java 2008-07-07 06:38:28 UTC (rev 1056)
+++ branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/DatabaseSession.java 2008-07-07 12:53:59 UTC (rev 1057)
@@ -49,6 +49,7 @@
import org.mulgara.resolver.spi.*;
import org.mulgara.rules.*;
import org.mulgara.server.Session;
+import org.mulgara.transaction.TransactionManagerFactory;
/**
* A database session.
@@ -112,8 +113,8 @@
private final MulgaraTransactionManager transactionManager;
private MulgaraTransactionFactory transactionFactory;
- private MulgaraInternalTransactionFactory internalFactory;
- private MulgaraExternalTransactionFactory externalFactory;
+ private final MulgaraInternalTransactionFactory internalFactory;
+ private final MulgaraExternalTransactionFactory externalFactory;
/** the default maximum transaction duration */
private final long defaultTransactionTimeout;
@@ -144,6 +145,8 @@
*
* @param transactionManager the source of transactions for this session,
* never <code>null</code>
+ * @param transactionManagerFactory factory for internal jta transaction-manager
+ * for this session, never <code>null</code>
* @param securityAdapterList {@link List} of {@link SecurityAdapter}s to be
* consulted before permitting operations, never <code>null</code>
* @param symbolicTransformationList {@link List} of
@@ -180,6 +183,7 @@
* @throws IllegalArgumentException if any argument is <code>null</code>
*/
DatabaseSession(MulgaraTransactionManager transactionManager,
+ TransactionManagerFactory transactionManagerFactory,
List<SecurityAdapter> securityAdapterList,
List<SymbolicTransformation> symbolicTransformationList,
ResolverSessionFactory resolverSessionFactory,
@@ -205,6 +209,8 @@
// Validate parameters
if (transactionManager == null) {
throw new IllegalArgumentException("Null 'transactionManager' parameter");
+ } else if (transactionManagerFactory == null) {
+ throw new IllegalArgumentException("Null 'transactionManagerFactory' parameter");
} else if (securityAdapterList == null) {
throw new IllegalArgumentException("Null 'securityAdapterList' parameter");
} else if (symbolicTransformationList == null) {
@@ -256,7 +262,9 @@
this.ruleLoaderClassName = ruleLoaderClassName;
this.transactionFactory = null;
- this.internalFactory = null;
+ this.externalFactory = new MulgaraExternalTransactionFactory(this, transactionManager);
+ this.internalFactory =
+ new MulgaraInternalTransactionFactory(this, transactionManager, transactionManagerFactory);
this.transactionTimeout = defaultTransactionTimeout;
this.idleTimeout = defaultIdleTimeout;
@@ -269,6 +277,7 @@
* Non-rule version of the constructor. Accepts all parameters except ruleLoaderClassName.
*/
DatabaseSession(MulgaraTransactionManager transactionManager,
+ TransactionManagerFactory transactionManagerFactory,
List<SecurityAdapter> securityAdapterList,
List<SymbolicTransformation> symbolicTransformationList,
ResolverSessionFactory resolverSessionFactory,
@@ -281,7 +290,7 @@
ContentHandlerManager contentHandlers,
Set<ResolverFactory> cachedResolverFactorySet,
URI temporaryModelTypeURI) throws ResolverFactoryException {
- this(transactionManager, securityAdapterList, symbolicTransformationList, resolverSessionFactory,
+ this(transactionManager, transactionManagerFactory, securityAdapterList, symbolicTransformationList, resolverSessionFactory,
systemResolverFactory, temporaryResolverFactory, resolverFactoryList, externalResolverFactoryMap,
internalResolverFactoryMap, metadata, contentHandlers, cachedResolverFactorySet,
temporaryModelTypeURI, 0, 0, null);
@@ -532,7 +541,7 @@
if (logger.isDebugEnabled()) logger.debug("setAutoCommit(" + autoCommit + ") called.");
assertInternallyManagedXA();
try {
- internalFactory.setAutoCommit(this, autoCommit);
+ internalFactory.setAutoCommit(autoCommit);
} catch (MulgaraTransactionException em) {
throw new QueryException("Error setting autocommit", em);
}
@@ -543,7 +552,7 @@
logger.debug("Committing transaction");
assertInternallyManagedXA();
try {
- internalFactory.commit(this);
+ internalFactory.commit();
} catch (MulgaraTransactionException em) {
throw new QueryException("Error performing commit", em);
}
@@ -554,7 +563,7 @@
logger.debug("Rollback transaction");
assertInternallyManagedXA();
try {
- internalFactory.rollback(this);
+ internalFactory.rollback();
} catch (MulgaraTransactionException em) {
throw new QueryException("Error performing rollback", em);
}
@@ -564,11 +573,25 @@
public void close() throws QueryException {
logger.debug("Closing session");
try {
- transactionManager.closingSession(this);
transactionFactory = null;
- } catch (MulgaraTransactionException em2) {
- logger.error("Error force-closing session", em2);
- throw new QueryException("Error force-closing session.", em2);
+ externalFactory.closingSession();
+ } catch (MulgaraTransactionException em) {
+ logger.error("Error force-closing session", em);
+ throw new QueryException("Error force-closing session.", em);
+ } finally {
+ try {
+ internalFactory.closingSession();
+ } catch (MulgaraTransactionException em2) {
+ logger.error("Error force-closing session", em2);
+ throw new QueryException("Error force-closing session.", em2);
+ } finally {
+ try {
+ transactionManager.closingSession(this);
+ } catch (MulgaraTransactionException em2) {
+ logger.error("Error force-closing session", em2);
+ throw new QueryException("Error force-closing session.", em2);
+ }
+ }
}
}
@@ -638,7 +661,7 @@
private void execute(Operation operation, String errorString) throws QueryException {
ensureTransactionFactorySelected();
try {
- MulgaraTransaction transaction = transactionFactory.getTransaction(this, operation.isWriteOperation());
+ MulgaraTransaction transaction = transactionFactory.getTransaction(operation.isWriteOperation());
transaction.execute(operation, metadata);
} catch (MulgaraTransactionException em) {
logger.debug("Error executing operation: " + errorString, em);
@@ -684,8 +707,8 @@
private void assertInternallyManagedXA() throws QueryException {
if (transactionFactory == null) {
- transactionFactory = internalFactory = transactionManager.getInternalFactory();
- } else if (internalFactory == null) {
+ transactionFactory = internalFactory;
+ } else if (transactionFactory != internalFactory) {
throw new QueryException("Attempt to use internal transaction control in externally managed session");
}
}
@@ -693,8 +716,8 @@
private void assertExternallyManagedXA() throws QueryException {
if (transactionFactory == null) {
- transactionFactory = externalFactory = transactionManager.getExternalFactory();
- } else if (externalFactory == null) {
+ transactionFactory = externalFactory;
+ } else if (transactionFactory != externalFactory) {
throw new QueryException("Attempt to use external transaction control in internally managed session");
}
}
@@ -702,13 +725,13 @@
public XAResource getXAResource() throws QueryException {
assertExternallyManagedXA();
- return externalFactory.getXAResource(this, true);
+ return externalFactory.getXAResource(true);
}
public XAResource getReadOnlyXAResource() throws QueryException {
assertExternallyManagedXA();
- return externalFactory.getXAResource(this, false);
+ return externalFactory.getXAResource(false);
}
public void setIdleTimeout(long millis) {
Modified: branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/LocalJRDFDatabaseSession.java
===================================================================
--- branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/LocalJRDFDatabaseSession.java 2008-07-07 06:38:28 UTC (rev 1056)
+++ branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/LocalJRDFDatabaseSession.java 2008-07-07 12:53:59 UTC (rev 1057)
@@ -45,6 +45,7 @@
import org.mulgara.resolver.spi.*;
import org.mulgara.server.*;
import org.mulgara.store.statement.StatementStore;
+import org.mulgara.transaction.TransactionManagerFactory;
/**
* A JRDF database session.
@@ -115,6 +116,7 @@
* @throws IllegalArgumentException if any argument is <code>null</code>
*/
LocalJRDFDatabaseSession(MulgaraTransactionManager transactionManager,
+ TransactionManagerFactory transactionManagerFactory,
List securityAdapterList, List symbolicTransformationList,
ResolverSessionFactory resolverSessionFactory,
SystemResolverFactory systemResolverFactory,
@@ -123,8 +125,8 @@
DatabaseMetadata metadata, ContentHandlerManager contentHandlers,
Set cachedResolverFactorySet, URI temporaryModelTypeURI)
throws ResolverFactoryException {
- super(transactionManager, securityAdapterList, symbolicTransformationList,
- resolverSessionFactory,
+ super(transactionManager, transactionManagerFactory, securityAdapterList,
+ symbolicTransformationList, resolverSessionFactory,
systemResolverFactory, temporaryResolverFactory, resolverFactoryList,
externalResolverFactoryMap, internalResolverFactoryMap, metadata,
contentHandlers, cachedResolverFactorySet, temporaryModelTypeURI);
Modified: branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/MulgaraExternalTransactionFactory.java
===================================================================
--- branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/MulgaraExternalTransactionFactory.java 2008-07-07 06:38:28 UTC (rev 1056)
+++ branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/MulgaraExternalTransactionFactory.java 2008-07-07 12:53:59 UTC (rev 1057)
@@ -21,6 +21,7 @@
// Java2 packages
import java.util.Collections;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.transaction.xa.XAResource;
@@ -31,7 +32,6 @@
// Local packages
import org.mulgara.query.MulgaraTransactionException;
import org.mulgara.query.QueryException;
-import org.mulgara.util.Assoc1toNMap;
/**
* Manages external transactions.
@@ -48,41 +48,40 @@
*/
public class MulgaraExternalTransactionFactory extends MulgaraTransactionFactory {
- private Map<DatabaseSession, MulgaraExternalTransaction> associatedTransaction;
- private Assoc1toNMap<DatabaseSession, MulgaraExternalTransaction> sessionXAMap;
+ private final Set<MulgaraExternalTransaction> transactions;
- private Map<DatabaseSession, MulgaraXAResourceContext> xaResources;
+ private final MulgaraXAResourceContext xaResource;
- public MulgaraExternalTransactionFactory(MulgaraTransactionManager manager) {
- super(manager);
+ private MulgaraExternalTransaction associatedTransaction;
- this.associatedTransaction = new HashMap<DatabaseSession, MulgaraExternalTransaction>();
- this.sessionXAMap = new Assoc1toNMap<DatabaseSession, MulgaraExternalTransaction>();
- this.xaResources = new HashMap<DatabaseSession, MulgaraXAResourceContext>();
+ public MulgaraExternalTransactionFactory(DatabaseSession session, MulgaraTransactionManager manager) {
+ super(session, manager);
+
+ this.associatedTransaction = null;
+ this.transactions = new HashSet<MulgaraExternalTransaction>();
+ this.xaResource = new MulgaraXAResourceContext(this, session);
}
- public MulgaraTransaction getTransaction(final DatabaseSession session, boolean write)
- throws MulgaraTransactionException {
+ public MulgaraTransaction getTransaction(boolean write) throws MulgaraTransactionException {
acquireMutex();
try {
- MulgaraExternalTransaction xa = associatedTransaction.get(session);
- if (xa == null) {
+ if (associatedTransaction == null) {
throw new MulgaraTransactionException("No externally mediated transaction associated with session");
- } else if (write && xa != writeTransaction) {
+ } else if (write && associatedTransaction != writeTransaction) {
throw new MulgaraTransactionException("RO-transaction associated with session when requesting write operation");
}
- return xa;
+ return associatedTransaction;
} finally {
releaseMutex();
}
}
- protected MulgaraExternalTransaction createTransaction(final DatabaseSession session, Xid xid, boolean write)
+ protected MulgaraExternalTransaction createTransaction(Xid xid, boolean write)
throws MulgaraTransactionException {
acquireMutex();
try {
- if (associatedTransaction.get(session) != null) {
+ if (associatedTransaction != null) {
throw new MulgaraTransactionException(
"Attempt to initiate transaction with existing transaction active with session");
}
@@ -91,18 +90,18 @@
}
if (write) {
- // see comment in MulgaraInternalTransactionFactory regarding releasing the lock here
- runWithoutMutex(new TransactionOperation() {
- public void execute() throws MulgaraTransactionException {
- manager.obtainWriteLock(session);
- }
- });
+ // see comment in MulgaraInternalTransactionFactory regarding releasing the lock here
+ runWithoutMutex(new TransactionOperation() {
+ public void execute() throws MulgaraTransactionException {
+ manager.obtainWriteLock(session);
+ }
+ });
try {
MulgaraExternalTransaction xa = new MulgaraExternalTransaction(this, xid, session.newOperationContext(true));
writeTransaction = xa;
- associatedTransaction.put(session, xa);
- sessionXAMap.put(session, xa);
- transactionCreated(xa, session);
+ associatedTransaction = xa;
+ transactions.add(xa);
+ transactionCreated(xa);
return xa;
} catch (Throwable th) {
@@ -112,9 +111,9 @@
} else {
try {
MulgaraExternalTransaction xa = new MulgaraExternalTransaction(this, xid, session.newOperationContext(false));
- associatedTransaction.put(session, xa);
- sessionXAMap.put(session, xa);
- transactionCreated(xa, session);
+ associatedTransaction = xa;
+ transactions.add(xa);
+ transactionCreated(xa);
return xa;
} catch (QueryException eq) {
@@ -126,83 +125,57 @@
}
}
- public Set<MulgaraExternalTransaction> getTransactionsForSession(DatabaseSession session) {
- acquireMutex();
- try {
- Set<MulgaraExternalTransaction> xas = sessionXAMap.getN(session);
- return xas != null ? xas : Collections.<MulgaraExternalTransaction>emptySet();
- } finally {
- releaseMutex();
- }
+ protected Set<MulgaraExternalTransaction> getTransactions() {
+ return transactions;
}
- public XAResource getXAResource(DatabaseSession session, boolean writing) {
+ public XAResource getXAResource(boolean writing) {
acquireMutex();
try {
- MulgaraXAResourceContext xarc = xaResources.get(session);
- if (xarc == null) {
- xarc = new MulgaraXAResourceContext(this, session);
- xaResources.put(session, xarc);
- }
-
- return xarc.getResource(writing);
+ return xaResource.getResource(writing);
} finally {
releaseMutex();
}
}
- public void closingSession(DatabaseSession session) throws MulgaraTransactionException {
- acquireMutex();
- try {
- try {
- super.closingSession(session);
- } finally {
- xaResources.remove(session);
- }
- } finally {
- releaseMutex();
- }
- }
-
public void transactionComplete(MulgaraExternalTransaction xa)
throws MulgaraTransactionException {
acquireMutex();
- super.transactionComplete(xa);
-
try {
+ super.transactionComplete(xa);
+
if (xa == null) {
throw new IllegalArgumentException("Null transaction indicated completion");
}
- DatabaseSession session = sessionXAMap.get1(xa);
if (xa == writeTransaction) {
manager.releaseWriteLock(session);
writeTransaction = null;
}
- sessionXAMap.removeN(xa);
- if (associatedTransaction.get(session) == xa) {
- associatedTransaction.remove(session);
+ transactions.remove(xa);
+ if (associatedTransaction == xa) {
+ associatedTransaction = null;
}
} finally {
releaseMutex();
}
}
- public boolean hasAssociatedTransaction(DatabaseSession session) {
+ public boolean hasAssociatedTransaction() {
acquireMutex();
try {
- return associatedTransaction.get(session) != null;
+ return associatedTransaction != null;
} finally {
releaseMutex();
}
}
- public boolean associateTransaction(DatabaseSession session, MulgaraExternalTransaction xa) {
+ public boolean associateTransaction(MulgaraExternalTransaction xa) {
acquireMutex();
try {
- if (associatedTransaction.get(session) != null) {
+ if (associatedTransaction != null) {
return false;
} else {
- associatedTransaction.put(session, xa);
+ associatedTransaction = xa;
return true;
}
} finally {
@@ -210,24 +183,37 @@
}
}
- public MulgaraExternalTransaction getAssociatedTransaction(DatabaseSession session) {
+ public MulgaraExternalTransaction getAssociatedTransaction() {
acquireMutex();
try {
- return associatedTransaction.get(session);
+ return associatedTransaction;
} finally {
releaseMutex();
}
}
- public void disassociateTransaction(DatabaseSession session, MulgaraExternalTransaction xa)
+ public void disassociateTransaction(MulgaraExternalTransaction xa)
throws MulgaraTransactionException {
acquireMutex();
try {
- if (associatedTransaction.get(session) == xa) {
- associatedTransaction.remove(session);
+ if (associatedTransaction == xa) {
+ associatedTransaction = null;
}
} finally {
releaseMutex();
}
}
+
+ public void closingSession() throws MulgaraTransactionException {
+ acquireMutex();
+ try {
+ try {
+ super.closingSession();
+ } finally {
+ transactions.clear();
+ }
+ } finally {
+ releaseMutex();
+ }
+ }
}
Modified: branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/MulgaraInternalTransactionFactory.java
===================================================================
--- branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/MulgaraInternalTransactionFactory.java 2008-07-07 06:38:28 UTC (rev 1056)
+++ branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/MulgaraInternalTransactionFactory.java 2008-07-07 12:53:59 UTC (rev 1057)
@@ -57,37 +57,40 @@
Logger.getLogger(MulgaraInternalTransactionFactory.class.getName());
/** Set of sessions whose transactions have been rolledback.*/
- private Set<DatabaseSession> failedSessions;
+ private boolean isFailed;
/** Map of threads to active transactions. */
- private Map<Thread, MulgaraTransaction> activeTransactions;
+ private final Map<Thread, MulgaraTransaction> activeTransactions;
- /** Map of transactions to associated sessions. */
- private Map<MulgaraTransaction, DatabaseSession> xaSessionMap;
+ /** Are we in auto-commit mode. */
+ public boolean autoCommit;
- /** Per session info. */
- private Map<DatabaseSession, SessionInfo> sessionInfoMap;
+ /** All uncompleted transactions (may be more than 1 because of unclosed answers) */
+ public final Set<MulgaraTransaction> transactions;
+ /** Currently associated explicit transaction */
+ public MulgaraInternalTransaction explicitXA;
+
private final TransactionManager transactionManager;
- public MulgaraInternalTransactionFactory(MulgaraTransactionManager manager, TransactionManagerFactory transactionManagerFactory) {
- super(manager);
+ public MulgaraInternalTransactionFactory(DatabaseSession session, MulgaraTransactionManager manager,
+ TransactionManagerFactory transactionManagerFactory) {
+ super(session, manager);
- this.failedSessions = new HashSet<DatabaseSession>();
+ this.isFailed = false;
this.activeTransactions = new HashMap<Thread, MulgaraTransaction>();
- this.xaSessionMap = new HashMap<MulgaraTransaction, DatabaseSession>();
- this.sessionInfoMap = new HashMap<DatabaseSession, SessionInfo>();
+ this.autoCommit = true;
+ this.transactions = new HashSet<MulgaraTransaction>();
+ this.explicitXA = null;
this.transactionManager = transactionManagerFactory.newTransactionManager();
}
- public MulgaraTransaction getTransaction(final DatabaseSession session, boolean write)
- throws MulgaraTransactionException {
+ public MulgaraTransaction getTransaction(boolean write) throws MulgaraTransactionException {
acquireMutex();
try {
- SessionInfo sessInfo = getOrCreateSessionInfo(session);
- if (sessInfo.explicitXA != null) {
- return sessInfo.explicitXA;
+ if (explicitXA != null) {
+ return explicitXA;
}
try {
@@ -106,7 +109,7 @@
try {
assert writeTransaction == null;
writeTransaction = transaction =
- new MulgaraInternalTransaction(this, session.newOperationContext(true));
+ new MulgaraInternalTransaction(this, session.newOperationContext(true));
} catch (Throwable th) {
manager.releaseWriteLock(session);
throw new MulgaraTransactionException("Error creating write transaction", th);
@@ -115,9 +118,8 @@
transaction = new MulgaraInternalTransaction(this, session.newOperationContext(false));
}
- xaSessionMap.put(transaction, session);
- sessInfo.transactions.add(transaction);
- transactionCreated(transaction, session);
+ transactions.add(transaction);
+ transactionCreated(transaction);
return transaction;
} catch (MulgaraTransactionException em) {
@@ -130,26 +132,15 @@
}
}
- public Set<MulgaraTransaction> getTransactionsForSession(DatabaseSession session) {
- acquireMutex();
- try {
- SessionInfo sessInfo = sessionInfoMap.get(session);
- return sessInfo == null ? Collections.<MulgaraTransaction>emptySet() : sessInfo.transactions;
- } finally {
- releaseMutex();
- }
+ public Set<MulgaraTransaction> getTransactions() {
+ return transactions;
}
- public MulgaraTransaction newMulgaraTransaction(DatabaseOperationContext context)
- throws MulgaraTransactionException {
- return new MulgaraInternalTransaction(this, context);
- }
-
- public void commit(DatabaseSession session) throws MulgaraTransactionException {
+ public void commit() throws MulgaraTransactionException {
acquireMutex();
try {
- if (failedSessions.contains(session)) {
+ if (isFailed) {
throw new MulgaraTransactionException("Attempting to commit failed session");
} else if (!manager.isHoldingWriteLock(session)) {
throw new MulgaraTransactionException(
@@ -158,8 +149,8 @@
manager.reserveWriteLock(session);
try {
- setAutoCommit(session, true);
- setAutoCommit(session, false);
+ setAutoCommit(true);
+ setAutoCommit(false);
} finally {
manager.releaseReserve(session);
}
@@ -174,7 +165,7 @@
*
* This needs to be distinguished from an implicit rollback triggered by failure.
*/
- public void rollback(DatabaseSession session) throws MulgaraTransactionException {
+ public void rollback() throws MulgaraTransactionException {
acquireMutex();
try {
if (manager.isHoldingWriteLock(session)) {
@@ -182,10 +173,10 @@
try {
try {
writeTransaction.execute(new TransactionOperation() {
- public void execute() throws MulgaraTransactionException {
- writeTransaction.dereference();
- ((MulgaraInternalTransaction)writeTransaction).explicitRollback();
- }
+ public void execute() throws MulgaraTransactionException {
+ writeTransaction.dereference();
+ ((MulgaraInternalTransaction)writeTransaction).explicitRollback();
+ }
});
// FIXME: Should be checking status here, not writelock.
if (manager.isHoldingWriteLock(session)) {
@@ -194,16 +185,16 @@
new MulgaraTransactionException("Rollback failed to terminate write transaction"));
}
} finally {
- sessionInfoMap.get(session).explicitXA = null;
- setAutoCommit(session, false);
+ explicitXA = null;
+ setAutoCommit(false);
}
} finally {
manager.releaseReserve(session);
}
- } else if (failedSessions.contains(session)) {
- sessionInfoMap.get(session).explicitXA = null;
- failedSessions.remove(session);
- setAutoCommit(session, false);
+ } else if (isFailed) {
+ explicitXA = null;
+ isFailed = false;
+ setAutoCommit(false);
} else {
throw new MulgaraTransactionException(
"Attempt to rollback while not in the current writing transaction");
@@ -213,21 +204,18 @@
}
}
- public void setAutoCommit(DatabaseSession session, boolean autoCommit)
- throws MulgaraTransactionException {
+ public void setAutoCommit(boolean autoCommit) throws MulgaraTransactionException {
acquireMutex();
try {
- if (manager.isHoldingWriteLock(session) && failedSessions.contains(session)) {
+ if (manager.isHoldingWriteLock(session) && isFailed) {
writeTransaction.abortTransaction("Session failed and still holding writeLock",
- new MulgaraTransactionException("Failed Session in setAutoCommit"));
+ new MulgaraTransactionException("Failed Session in setAutoCommit"));
}
- SessionInfo sessInfo = getOrCreateSessionInfo(session);
-
- if (manager.isHoldingWriteLock(session) || failedSessions.contains(session)) {
+ if (manager.isHoldingWriteLock(session) || isFailed) {
if (autoCommit) {
- sessInfo.autoCommit = true;
- sessInfo.explicitXA = null;
+ this.autoCommit = true;
+ this.explicitXA = null;
// AutoCommit off -> on === branch on current state of transaction.
if (manager.isHoldingWriteLock(session)) {
@@ -253,9 +241,9 @@
manager.releaseWriteLock(session);
}
}
- } else if (failedSessions.contains(session)) {
+ } else if (isFailed) {
// Within failed transaction - cleanup.
- failedSessions.remove(session);
+ isFailed = false;
}
} else {
if (!manager.isHoldingWriteLock(session)) {
@@ -268,16 +256,16 @@
}
}
} else {
- sessInfo.explicitXA = null;
+ explicitXA = null;
if (autoCommit) {
// AutoCommit on -> on === no-op. Log info.
logger.info("Attempting to set autocommit true without setting it false");
} else {
// AutoCommit on -> off == Start new transaction.
- getTransaction(session, true); // Set's writeTransaction.
+ getTransaction(true); // Set's writeTransaction.
writeTransaction.reference();
- sessInfo.explicitXA = writeTransaction;
- sessInfo.autoCommit = false;
+ explicitXA = (MulgaraInternalTransaction) writeTransaction;
+ this.autoCommit = false;
}
}
} finally {
@@ -301,7 +289,7 @@
throw new MulgaraTransactionException("Attempt to start transaction twice");
}
- setTransactionTimeout((int) (xaSessionMap.get(transaction).getTransactionTimeout() / 1000));
+ setTransactionTimeout((int) (session.getTransactionTimeout() / 1000));
transactionManager.begin();
Transaction jtaTrans = transactionManager.getTransaction();
@@ -326,7 +314,7 @@
} else if (activeTransactions.containsValue(transaction)) {
throw new MulgaraTransactionException("Attempt to resume active transaction");
}
-
+
try {
transactionManager.resume(jtaXA);
activeTransactions.put(Thread.currentThread(), transaction);
@@ -348,8 +336,7 @@
"Attempt to suspend transaction from outside thread");
}
- SessionInfo sessInfo = sessionInfoMap.get(xaSessionMap.get(transaction));
- if (sessInfo.autoCommit && transaction == writeTransaction) {
+ if (autoCommit && transaction == writeTransaction) {
logger.error("Attempt to suspend write transaction without setting AutoCommit Off");
throw new MulgaraTransactionException(
"Attempt to suspend write transaction without setting AutoCommit Off");
@@ -373,16 +360,13 @@
}
}
- public void closingSession(DatabaseSession session) throws MulgaraTransactionException {
+ public void closingSession() throws MulgaraTransactionException {
acquireMutex();
try {
try {
- super.closingSession(session);
+ super.closingSession();
} finally {
- SessionInfo sessInfo = sessionInfoMap.remove(session);
- if (sessInfo != null) {
- xaSessionMap.keySet().removeAll(sessInfo.transactions);
- }
+ transactions.clear();
}
} finally {
releaseMutex();
@@ -391,14 +375,11 @@
public void transactionComplete(MulgaraTransaction transaction) throws MulgaraTransactionException {
acquireMutex();
- super.transactionComplete(transaction);
-
try {
+ super.transactionComplete(transaction);
+
logger.debug("Transaction Complete");
- DatabaseSession session = xaSessionMap.get(transaction);
- if (session == null) {
- throw new MulgaraTransactionException("No associated session found for transaction");
- }
+
if (transaction == writeTransaction) {
if (manager.isHoldingWriteLock(session)) {
manager.releaseWriteLock(session);
@@ -406,8 +387,7 @@
}
}
- xaSessionMap.remove(transaction);
- sessionInfoMap.get(session).transactions.remove(transaction);
+ transactions.remove(transaction);
activeTransactions.remove(Thread.currentThread());
} finally {
releaseMutex();
@@ -419,9 +399,8 @@
try {
try {
// Make sure this cleans up the transaction metadata - this transaction is DEAD!
- SessionInfo sessInfo = sessionInfoMap.get(xaSessionMap.get(transaction));
- if (!sessInfo.autoCommit && transaction == writeTransaction) {
- failedSessions.add(xaSessionMap.get(transaction));
+ if (!autoCommit && transaction == writeTransaction) {
+ isFailed = true;
}
transactionComplete(transaction);
} catch (Throwable th) {
@@ -440,21 +419,4 @@
logger.warn("Unable to set transaction timeout: " + transactionTimeout, es);
}
}
-
- private SessionInfo getOrCreateSessionInfo(DatabaseSession session) {
- SessionInfo info = sessionInfoMap.get(session);
- if (info == null)
- sessionInfoMap.put(session, info = new SessionInfo());
- return info;
- }
-
- private static class SessionInfo {
- public boolean autoCommit = true;
-
- /** All uncompleted transactions (may be more than 1 because of unclosed answers) */
- public Set<MulgaraTransaction> transactions = new HashSet<MulgaraTransaction>();
-
- /** Currently associated explicit transaction */
- public MulgaraTransaction explicitXA;
- }
}
Modified: branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/MulgaraTransactionFactory.java
===================================================================
--- branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/MulgaraTransactionFactory.java 2008-07-07 06:38:28 UTC (rev 1056)
+++ branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/MulgaraTransactionFactory.java 2008-07-07 12:53:59 UTC (rev 1057)
@@ -66,6 +66,7 @@
protected final IdleReaper idleReaperTask;
protected long idleTimeout;
protected ExtXAReaper extXAReaperTask;
+ protected final DatabaseSession session;
/**
* Contains a reference the the current writing transaction IFF it is managed
@@ -76,7 +77,8 @@
private ReentrantLock mutex;
- protected MulgaraTransactionFactory(MulgaraTransactionManager manager) {
+ protected MulgaraTransactionFactory(DatabaseSession session, MulgaraTransactionManager manager) {
+ this.session = session;
this.manager = manager;
this.mutex = new ReentrantLock();
this.writeTransaction = null;
@@ -86,7 +88,7 @@
}
- protected void transactionCreated(MulgaraTransaction transaction, DatabaseSession session) {
+ protected void transactionCreated(MulgaraTransaction transaction) {
if (transaction != writeTransaction)
return;
@@ -110,17 +112,17 @@
* otherwise creates a new transaction context and associates it with the
* session.
*/
- public abstract MulgaraTransaction getTransaction(final DatabaseSession session, boolean write)
+ public abstract MulgaraTransaction getTransaction(boolean write)
throws MulgaraTransactionException;
-
- protected abstract Set<? extends MulgaraTransaction> getTransactionsForSession(DatabaseSession session);
+ protected abstract Set<? extends MulgaraTransaction> getTransactions();
+
/**
* Rollback, or abort all transactions associated with a DatabaseSession.
*
* Will only abort the transaction if the rollback attempt fails.
*/
- public void closingSession(DatabaseSession session) throws MulgaraTransactionException {
+ public void closingSession() throws MulgaraTransactionException {
acquireMutex();
logger.debug("Cleaning up any stale transactions on session close");
try {
@@ -156,7 +158,7 @@
logger.debug("Session does not hold write-lock");
}
- for (MulgaraTransaction transaction : getTransactionsForSession(session)) {
+ for (MulgaraTransaction transaction : getTransactions()) {
try {
// This is final so we can create the closure.
final MulgaraTransaction xa = transaction;
Modified: branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/MulgaraTransactionManager.java
===================================================================
--- branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/MulgaraTransactionManager.java 2008-07-07 06:38:28 UTC (rev 1056)
+++ branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/MulgaraTransactionManager.java 2008-07-07 12:53:59 UTC (rev 1057)
@@ -30,17 +30,14 @@
// Local packages
import org.mulgara.query.MulgaraTransactionException;
-import org.mulgara.transaction.TransactionManagerFactory;
/**
* Manages the Write-Lock.
*
* Manages tracking the ownership of the write-lock.
- * Provides new/existing TransactionContext's to DatabaseSession on request.
- * Note: Returns new context unless Session is currently in a User Demarcated Transaction.
* Provides a facility to trigger a heuristic rollback of any transactions still
* valid on session close.
- * Maintains the write-queue and any timeout algorithm desired.
+ * Maintains the write-queue
*
* @created 2006-10-06
*
@@ -74,29 +71,14 @@
private final ReentrantLock mutex;
private final Condition writeLockCondition;
- private final MulgaraInternalTransactionFactory internalFactory;
- private final MulgaraExternalTransactionFactory externalFactory;
-
- public MulgaraTransactionManager(TransactionManagerFactory transactionManagerFactory) {
+ public MulgaraTransactionManager() {
this.sessionHoldingWriteLock = null;
this.sessionReservingWriteLock = null;
this.mutex = new ReentrantLock();
this.writeLockCondition = this.mutex.newCondition();
-
- this.internalFactory = new MulgaraInternalTransactionFactory(this, transactionManagerFactory);
- this.externalFactory = new MulgaraExternalTransactionFactory(this);
}
- MulgaraInternalTransactionFactory getInternalFactory() {
- return internalFactory;
- }
-
- MulgaraExternalTransactionFactory getExternalFactory() {
- return externalFactory;
- }
-
-
/**
* Obtains the write lock.
*/
@@ -224,28 +206,12 @@
}
public void closingSession(DatabaseSession session) throws MulgaraTransactionException {
- // Calls to final fields do not require mutex. As both of these calls
- // potentially call back into the manager, calling these while holding the
- // lock can invalidate lock-ordering and result in a deadlock.
- Throwable error = null;
- try {
- internalFactory.closingSession(session);
- } catch (Throwable th) {
- logger.error("Error signalling session-close to internal xa-factory", th);
- error = (error == null) ? th : error;
- }
-
- try {
- externalFactory.closingSession(session);
- } catch (Throwable th) {
- logger.error("Error signalling session-close to external xa-factory", th);
- error = (error == null) ? th : error;
- }
-
// This code should not be required, but is there to ensure the manager is
// reset regardless of errors in the factories.
acquireMutex();
try {
+ Throwable error = null;
+
if (writeLockReserved(session)) {
try {
releaseReserve(session);
Modified: branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/MulgaraXAResourceContext.java
===================================================================
--- branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/MulgaraXAResourceContext.java 2008-07-07 06:38:28 UTC (rev 1056)
+++ branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/MulgaraXAResourceContext.java 2008-07-07 12:53:59 UTC (rev 1057)
@@ -208,7 +208,7 @@
try {
// If XA is currently associated with session, disassociate it.
- factory.disassociateTransaction(session, xa);
+ factory.disassociateTransaction(xa);
} catch (MulgaraTransactionException em) {
logger.error("Error disassociating transaction from session", em);
throw new XAException(XAException.XAER_PROTO);
@@ -366,12 +366,12 @@
case TMNOFLAGS:
if (xa2xid.containsN(xid)) {
throw new XAException(XAException.XAER_DUPID);
- } else if (factory.hasAssociatedTransaction(session)) {
+ } else if (factory.hasAssociatedTransaction()) {
throw new XAException(XAException.XA_RBDEADLOCK);
} else {
// FIXME: Need to consider read-only transactions here.
try {
- MulgaraExternalTransaction xa = factory.createTransaction(session, xid, writing);
+ MulgaraExternalTransaction xa = factory.createTransaction(xid, writing);
xa2xid.put(xa, xid);
} catch (MulgaraTransactionException em) {
logger.error("Failed to create transaction", em);
@@ -380,9 +380,9 @@
}
break;
case TMJOIN:
- if (!factory.hasAssociatedTransaction(session)) {
+ if (!factory.hasAssociatedTransaction()) {
throw new XAException(XAException.XAER_NOTA);
- } else if (!factory.getAssociatedTransaction(session).getXid().equals(xid)) {
+ } else if (!factory.getAssociatedTransaction().getXid().equals(xid)) {
throw new XAException(XAException.XAER_OUTSIDE);
}
break;
@@ -393,7 +393,7 @@
} else if (xa.isRollbacked()) {
throw new XAException(XAException.XA_RBROLLBACK);
} else {
- if (!factory.associateTransaction(session, xa)) {
+ if (!factory.associateTransaction(xa)) {
// session already associated with a transaction.
throw new XAException(XAException.XAER_PROTO);
}
@@ -416,7 +416,7 @@
*/
private DatabaseSession getSession() { return session; }
}
-
+
/**
* Used to replace the built in monitor to allow it to be properly released
* during potentially blocking operations. All potentially blocking
More information about the Mulgara-svn
mailing list