[Mulgara-svn] r977 - in branches/mgr-121-lockrecovery: conf src/jar/query/java/org/mulgara/server src/jar/resolver/java/org/mulgara/resolver src/jar/resolver-relational/java/org/mulgara/resolver/relational src/jar/resolver-test/java/org/mulgara/resolver/test src/jar/resolver-view/java/org/mulgara/resolver/view src/jar/server-beep/java/org/mulgara/server/beep src/jar/server-rmi/java/org/mulgara/server/rmi
andrae at mulgara.org
andrae at mulgara.org
Fri Jun 6 05:41:22 UTC 2008
Author: andrae
Date: 2008-06-05 22:41:21 -0700 (Thu, 05 Jun 2008)
New Revision: 977
Modified:
branches/mgr-121-lockrecovery/conf/mulgara-config.xml
branches/mgr-121-lockrecovery/conf/mulgara-embedded.dtd
branches/mgr-121-lockrecovery/conf/mulgara-embedded.xsd
branches/mgr-121-lockrecovery/src/jar/query/java/org/mulgara/server/Session.java
branches/mgr-121-lockrecovery/src/jar/resolver-relational/java/org/mulgara/resolver/relational/RelationalResolverUnitTest.java
branches/mgr-121-lockrecovery/src/jar/resolver-test/java/org/mulgara/resolver/test/TestResolverUnitTest.java
branches/mgr-121-lockrecovery/src/jar/resolver-view/java/org/mulgara/resolver/view/ViewResolverUnitTest.java
branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/AdvDatabaseSessionUnitTest.java
branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/BasicDatabaseSessionUnitTest.java
branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/Database.java
branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/DatabaseFactory.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/DatabaseSessionListQueryUnitTest.java
branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/DatabaseSessionUnitTest.java
branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/DatabaseUnitTest.java
branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/ExternalTransactionUnitTest.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
branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/XADatabaseSessionUnitTest.java
branches/mgr-121-lockrecovery/src/jar/server-beep/java/org/mulgara/server/beep/BEEPSession.java
branches/mgr-121-lockrecovery/src/jar/server-rmi/java/org/mulgara/server/rmi/RemoteSession.java
branches/mgr-121-lockrecovery/src/jar/server-rmi/java/org/mulgara/server/rmi/RemoteSessionWrapperSession.java
branches/mgr-121-lockrecovery/src/jar/server-rmi/java/org/mulgara/server/rmi/SessionWrapperRemoteSession.java
Log:
Updates from Ronald.
Splits the transaction idle-timeout into a maximum transaction-timeout (meeting JTA requirements); and a
maximum-idle-timeout (meeting more useful requirements).
If a transaction holds the write-lock (irrespective of activity) for longer than the maxTT, the transaction
will be aborted.
If a transaction holds the write-lock, and does not perform an operation for longer than the maxIT, the
transaction will be aborted.
The timeouts have a default value set on the database-instance from the mulgara-conf file. These defaults can
be overridden on a per-session basis by calling the appropriate set* methods on Session.
Note the idle reaper task runs on a 10s periodic basis, so the transaction abort may occur up to 10s after the
expiry of the timeout proper.
Modified: branches/mgr-121-lockrecovery/conf/mulgara-config.xml
===================================================================
--- branches/mgr-121-lockrecovery/conf/mulgara-config.xml 2008-06-06 04:50:54 UTC (rev 976)
+++ branches/mgr-121-lockrecovery/conf/mulgara-config.xml 2008-06-06 05:41:21 UTC (rev 977)
@@ -55,6 +55,9 @@
<!-- Maximum duration in seconds for transactions, a positive integer -->
<TransactionTimeout>604800</TransactionTimeout> <!-- one week -->
+ <!-- Maximum time in seconds a transaction may be idle, a positive integer -->
+ <IdleTimeout>3600</IdleTimeout> <!-- one hour -->
+
<!--
Database implementation to use, one of:
Modified: branches/mgr-121-lockrecovery/conf/mulgara-embedded.dtd
===================================================================
--- branches/mgr-121-lockrecovery/conf/mulgara-embedded.dtd 2008-06-06 04:50:54 UTC (rev 976)
+++ branches/mgr-121-lockrecovery/conf/mulgara-embedded.dtd 2008-06-06 05:41:21 UTC (rev 977)
@@ -1,4 +1,4 @@
-<!ELEMENT MulgaraConfig (ExternalConfigPaths?, MulgaraHost?, Jetty?, ServerName, RMIPort?, PersistencePath, DefaultGraph?, TransactionTimeout? TripleStoreImplementation, StartupScript?)>
+<!ELEMENT MulgaraConfig (ExternalConfigPaths?, MulgaraHost?, Jetty?, ServerName, RMIPort?, PersistencePath, DefaultGraph?, TransactionTimeout?, IdleTimeout?. TripleStoreImplementation, StartupScript?)>
<!ELEMENT ExternalConfigPaths (MulgaraLogging, WebDefault)>
@@ -27,6 +27,8 @@
<!ELEMENT TransactionTimeout (#PCDATA)>
+ <!ELEMENT IdleTimeout (#PCDATA)>
+
<!ELEMENT TripleStoreImplementation (#PCDATA)>
<!ELEMENT StartupScript (#PCDATA)>
Modified: branches/mgr-121-lockrecovery/conf/mulgara-embedded.xsd
===================================================================
--- branches/mgr-121-lockrecovery/conf/mulgara-embedded.xsd 2008-06-06 04:50:54 UTC (rev 976)
+++ branches/mgr-121-lockrecovery/conf/mulgara-embedded.xsd 2008-06-06 05:41:21 UTC (rev 977)
@@ -93,6 +93,7 @@
</xs:complexType>
</xs:element>
<xs:element name="TransactionTimeout" type="xs:int"/>
+ <xs:element name="IdleTimeout" type="xs:int"/>
<xs:element name="DefaultContentHandler">
<xs:complexType>
<xs:attribute name="type" type="xs:string" use="required"/>
@@ -119,7 +120,8 @@
<xs:element ref="RMIPort" minOccurs="0"/>
<xs:element ref="PersistencePath"/>
<xs:element ref="DefaultGraph" minOccurs="0"/>
- <xs:element ref="TransactionTimeout"/>
+ <xs:element ref="TransactionTimeout" minOccurs="0"/>
+ <xs:element ref="IdleTimeout" minOccurs="0"/>
<xs:element ref="TripleStoreImplementation"/>
<xs:element ref="RelatedQueryHandler"/>
<xs:element ref="SecurityAdapterFactory" minOccurs="0" maxOccurs="unbounded"/>
Modified: branches/mgr-121-lockrecovery/src/jar/query/java/org/mulgara/server/Session.java
===================================================================
--- branches/mgr-121-lockrecovery/src/jar/query/java/org/mulgara/server/Session.java 2008-06-06 04:50:54 UTC (rev 976)
+++ branches/mgr-121-lockrecovery/src/jar/query/java/org/mulgara/server/Session.java 2008-06-06 05:41:21 UTC (rev 977)
@@ -306,6 +306,30 @@
*/
public void login(URI securityDomain, String username, char[] password);
+ /**
+ * The maximum time a transaction may be idle before it is aborted. If not set a default
+ * value is used. This value is only used for new transactions and does not affect any currently
+ * running transactions.
+ *
+ * <p>This currently only affects write transactions.
+ *
+ * @param millis the number of milliseconds, or 0 for the default timeout
+ * @throws QueryException if there was an error talking to the server
+ */
+ public void setIdleTimeout(long millis) throws QueryException;
+
+ /**
+ * The maximum time a transaction may be active (started but neither committed nor rolled back)
+ * before it is aborted. If not set a default value is used. This value is only used for new
+ * transactions and does not affect any currently running transactions.
+ *
+ * <p>This currently only affects write transactions.
+ *
+ * @param millis the number of milliseconds, or 0 for the default timeout
+ * @throws QueryException if there was an error talking to the server
+ */
+ public void setTransactionTimeout(long millis) throws QueryException;
+
/**
* Obtain an XAResource for this Session.
*
Modified: branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/AdvDatabaseSessionUnitTest.java
===================================================================
--- branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/AdvDatabaseSessionUnitTest.java 2008-06-06 04:50:54 UTC (rev 976)
+++ branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/AdvDatabaseSessionUnitTest.java 2008-06-06 05:41:21 UTC (rev 977)
@@ -183,6 +183,7 @@
null, // no security domain
new JotmTransactionManagerFactory(),
0, // default transaction timeout
+ 0, // default idle timeout
nodePoolFactoryClassName, // persistent
new File(persistenceDirectory, "xaNodePool"),
stringPoolFactoryClassName, // persistent
@@ -1528,9 +1529,10 @@
logger.info("testConcurrentImplicitRecovery");
URI fileURI = new File("data/xatest-model1.rdf").toURI();
- database.setWriteLockTimeout(30000);
+ // test idle timeout
try {
Session session1 = database.newSession();
+ session1.setIdleTimeout(10000);
try {
session1.createModel(model3URI, null);
logger.debug("Obtaining autocommit for session1");
@@ -1589,9 +1591,9 @@
t2.start();
session1.setModel(model3URI, new ModelResource(fileURI));
- logger.debug("Sleeping for 40sec");
- Thread.sleep(40000);
- logger.debug("Slept for 40sec");
+ logger.debug("Sleeping for 20sec");
+ Thread.sleep(20000);
+ logger.debug("Slept for 20sec");
try {
t2.join(2000L);
} catch (InterruptedException ie) {
@@ -1605,6 +1607,8 @@
session1.commit();
} catch (QueryException eq) {
qeThrown = true;
+ } catch (IllegalStateException ise) {
+ qeThrown = true;
}
assertTrue("Commit should have failed due to lock timeout", qeThrown);
@@ -1617,6 +1621,99 @@
} catch (Exception e) {
fail(e);
}
+
+ // test transaction timeout
+ try {
+ Session session1 = database.newSession();
+ session1.setTransactionTimeout(10000);
+ try {
+ session1.createModel(model3URI, null);
+ logger.debug("Obtaining autocommit for session1");
+ session1.setAutoCommit(false);
+ logger.debug("Obtained autocommit for session1");
+
+ Thread t2 = new Thread("tx2Test") {
+ public void run() {
+ try {
+ Session session2 = database.newSession();
+ try {
+ logger.debug("Obtaining autocommit for session2");
+ session2.setAutoCommit(false);
+ logger.debug("Obtained autocommit for session2");
+ Variable subjectVariable = new Variable("subject");
+ Variable predicateVariable = new Variable("predicate");
+ Variable objectVariable = new Variable("object");
+
+ List<SelectElement> selectList = new ArrayList<SelectElement>(3);
+ selectList.add(subjectVariable);
+ selectList.add(predicateVariable);
+ selectList.add(objectVariable);
+
+ // Evaluate the query
+ Answer answer = session2.query(new Query(
+ selectList, // SELECT
+ new ModelResource(model3URI), // FROM
+ new ConstraintImpl(subjectVariable, // WHERE
+ predicateVariable,
+ objectVariable),
+ null, // HAVING
+ Arrays.asList(new Order[] { // ORDER BY
+ new Order(subjectVariable, true),
+ new Order(predicateVariable, true),
+ new Order(objectVariable, true)
+ }),
+ null, // LIMIT
+ 0, // OFFSET
+ new UnconstrainedAnswer() // GIVEN
+ ));
+
+ answer.beforeFirst();
+ assertFalse(answer.next());
+ answer.close();
+
+ logger.debug("Releasing autocommit for session2");
+ session2.setAutoCommit(true);
+ } finally {
+ session2.close();
+ }
+ } catch (Exception e) {
+ fail(e);
+ }
+ }
+ };
+ t2.start();
+
+ session1.setModel(model3URI, new ModelResource(fileURI));
+ logger.debug("Sleeping for 20sec");
+ Thread.sleep(20000);
+ logger.debug("Slept for 20sec");
+ try {
+ t2.join(2000L);
+ } catch (InterruptedException ie) {
+ logger.error("wait for tx2-terminated interrupted", ie);
+ fail(ie);
+ }
+ assertFalse("second transaction should've terminated", t2.isAlive());
+
+ boolean qeThrown = false;
+ try {
+ session1.commit();
+ } catch (QueryException eq) {
+ qeThrown = true;
+ } catch (IllegalStateException ise) {
+ qeThrown = true;
+ }
+
+ assertTrue("Commit should have failed due to lock timeout", qeThrown);
+
+ logger.debug("Releasing autocommit for session1");
+ session1.setAutoCommit(true);
+ } finally {
+ session1.close();
+ }
+ } catch (Exception e) {
+ fail(e);
+ }
}
Modified: branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/BasicDatabaseSessionUnitTest.java
===================================================================
--- branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/BasicDatabaseSessionUnitTest.java 2008-06-06 04:50:54 UTC (rev 976)
+++ branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/BasicDatabaseSessionUnitTest.java 2008-06-06 05:41:21 UTC (rev 977)
@@ -146,6 +146,7 @@
null, // no security domain
new JotmTransactionManagerFactory(),
0, // default transaction timeout
+ 0, // default idle timeout
nodePoolFactoryClassName, // persistent
null,
stringPoolFactoryClassName, // persistent
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-06-06 04:50:54 UTC (rev 976)
+++ branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/Database.java 2008-06-06 05:41:21 UTC (rev 977)
@@ -260,6 +260,11 @@
*/
private final MulgaraTransactionManager transactionManager;
+ /** the default maximum duration for a transaction, in milli-seconds */
+ private final long defaultTransactionTimeout;
+ /** the default maximum idle time for a transaction, in milli-seconds */
+ private final long defaultIdleTimeout;
+
/** The unique {@link URI} naming this database. Not read in this implementation. */
@SuppressWarnings("unused")
private final URI uri;
@@ -322,6 +327,7 @@
uri, // security domain
new JotmTransactionManagerFactory(),
config.getTransactionTimeout(),
+ config.getIdleTimeout(),
config.getPersistentNodePoolFactory().getType(),
DatabaseFactory.subdir(
directory,
@@ -375,9 +381,12 @@
* database is within, or <code>null</code> if this database is unsecured
* @param transactionManagerFactory the source for the
* {@link TransactionManager}, never <code>null</code>
- * @param transactionTimeout the number of seconds before transactions time
- * out, or zero to take the <var>transactionManagerFactory</var>'s default;
+ * @param transactionTimeout the default number of seconds before transactions
+ * time out, or zero to take the <var>transactionManagerFactory</var>'s default;
* never negative
+ * @param idleTimeout the default number of seconds a transaction may be idle before
+ * it is timed out, or zero to take the <var>transactionManagerFactory</var>'s
+ * default; never negative
* @param persistentNodePoolFactoryClassName the name of a
* {@link NodePoolFactory} implementation which will be used to generate
* persistent local nodes, never <code>null</code>
@@ -415,6 +424,7 @@
URI securityDomainURI,
TransactionManagerFactory transactionManagerFactory,
int transactionTimeout,
+ int idleTimeout,
String persistentNodePoolFactoryClassName,
File persistentNodePoolDirectory,
String persistentStringPoolFactoryClassName,
@@ -513,7 +523,8 @@
// FIXME: Migrate this code inside StringPoolSession. Pass config to StringPoolSession.
this.transactionManager = new MulgaraTransactionManager(transactionManagerFactory);
- transactionManager.setTransactionTimeout(transactionTimeout);
+ this.defaultTransactionTimeout = transactionTimeout * 1000L;
+ this.defaultIdleTimeout = idleTimeout * 1000L;
// Enable resolver initialization
if (logger.isDebugEnabled()) {
@@ -688,6 +699,8 @@
contentHandlers,
unmodifiableCachedResolverFactorySet,
temporaryModelTypeURI,
+ defaultTransactionTimeout,
+ defaultIdleTimeout,
ruleLoaderClassName);
// Updates metadata to reflect bootstrapped system model.
@@ -828,11 +841,6 @@
}
- public void setWriteLockTimeout(long timeout) {
- transactionManager.setLockTimeout(timeout);
- }
-
-
/**
* Flush all resources associated with the database into a recoverable state.
*/
@@ -900,6 +908,8 @@
contentHandlers,
unmodifiableCachedResolverFactorySet,
temporaryModelTypeURI,
+ defaultTransactionTimeout,
+ defaultIdleTimeout,
ruleLoaderClassName);
} catch (ResolverFactoryException e) {
throw new QueryException("Couldn't create session", e);
@@ -1149,6 +1159,8 @@
contentHandlers,
unmodifiableCachedResolverFactorySet,
temporaryModelTypeURI,
+ defaultTransactionTimeout,
+ defaultIdleTimeout,
ruleLoaderClassName);
}
catch (ResolverFactoryException e) {
Modified: branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/DatabaseFactory.java
===================================================================
--- branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/DatabaseFactory.java 2008-06-06 04:50:54 UTC (rev 976)
+++ branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/DatabaseFactory.java 2008-06-06 05:41:21 UTC (rev 977)
@@ -100,6 +100,7 @@
uri, // security domain
new JotmTransactionManagerFactory(),
config.getTransactionTimeout(),
+ config.getIdleTimeout(),
config.getPersistentNodePoolFactory().getType(),
subdir(directory, config.getPersistentNodePoolFactory().getDir()),
config.getPersistentStringPoolFactory().getType(),
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-06-06 04:50:54 UTC (rev 976)
+++ branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/DatabaseSession.java 2008-06-06 05:41:21 UTC (rev 977)
@@ -117,6 +117,18 @@
private MulgaraInternalTransactionFactory internalFactory;
private MulgaraExternalTransactionFactory externalFactory;
+ /** the default maximum transaction duration */
+ private final long defaultTransactionTimeout;
+
+ /** the default maximum transaction idle time */
+ private final long defaultIdleTimeout;
+
+ /** the maximum transaction duration */
+ private long transactionTimeout;
+
+ /** the maximum transaction idle time */
+ private long idleTimeout;
+
/** The name of the rule loader to use */
private String ruleLoaderClassName;
@@ -160,6 +172,13 @@
* never <code>null</code>
* @param temporaryModelTypeURI the URI of the model type to use to cache
* external models
+ * @param transactionTimeout the default number of milli-seconds before transactions
+ * time out, or zero to take the <var>transactionManagerFactory</var>'s default;
+ * never negative
+ * @param idleTimeout the default number of milli-seconds a transaction may be idle
+ * before it is timed out, or zero to take the <var>transactionManagerFactory</var>'s
+ * default; never negative
+ * @param ruleLoaderClassName the rule-loader class to use; may be null
* @throws IllegalArgumentException if any argument is <code>null</code>
*/
DatabaseSession(MulgaraTransactionManager transactionManager,
@@ -175,6 +194,8 @@
ContentHandlerManager contentHandlers,
Set<ResolverFactory> cachedResolverFactorySet,
URI temporaryModelTypeURI,
+ long transactionTimeout,
+ long idleTimeout,
String ruleLoaderClassName) throws ResolverFactoryException {
if (logger.isDebugEnabled()) {
@@ -210,6 +231,10 @@
throw new IllegalArgumentException("Null 'cachedResolverFactorySet' parameter");
} else if (temporaryModelTypeURI == null) {
throw new IllegalArgumentException("Null 'temporaryModelTypeURI' parameter");
+ } else if (transactionTimeout < 0) {
+ throw new IllegalArgumentException("negative 'transactionTimeout' parameter");
+ } else if (idleTimeout < 0) {
+ throw new IllegalArgumentException("negative 'idleTimeout' parameter");
} else if (ruleLoaderClassName == null) {
ruleLoaderClassName = DUMMY_RULE_LOADER;
}
@@ -228,15 +253,17 @@
this.contentHandlers = contentHandlers;
this.cachedResolverFactorySet = cachedResolverFactorySet;
this.temporaryModelTypeURI = temporaryModelTypeURI;
+ this.defaultTransactionTimeout = transactionTimeout;
+ this.defaultIdleTimeout = idleTimeout;
this.ruleLoaderClassName = ruleLoaderClassName;
this.transactionFactory = null;
this.internalFactory = null;
+ this.transactionTimeout = defaultTransactionTimeout;
+ this.idleTimeout = defaultIdleTimeout;
+
if (logger.isTraceEnabled()) logger.trace("Constructed DatabaseSession");
-
- // Set the transaction timeout to an hour
- transactionManager.setTransactionTimeout(3600);
}
@@ -259,7 +286,7 @@
this(transactionManager, securityAdapterList, symbolicTransformationList, resolverSessionFactory,
systemResolverFactory, temporaryResolverFactory, resolverFactoryList, externalResolverFactoryMap,
internalResolverFactoryMap, metadata, contentHandlers, cachedResolverFactorySet,
- temporaryModelTypeURI, "");
+ temporaryModelTypeURI, 0, 0, null);
}
//
@@ -685,4 +712,20 @@
assertExternallyManagedXA();
return externalFactory.getXAResource(this, false);
}
+
+ public void setIdleTimeout(long millis) {
+ idleTimeout = millis > 0 ? millis : defaultIdleTimeout;
+ }
+
+ public void setTransactionTimeout(long millis) {
+ transactionTimeout = millis > 0 ? millis : defaultTransactionTimeout;
+ }
+
+ public long getIdleTimeout() {
+ return idleTimeout;
+ }
+
+ public long getTransactionTimeout() {
+ return transactionTimeout;
+ }
}
Modified: branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/DatabaseSessionListQueryUnitTest.java
===================================================================
--- branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/DatabaseSessionListQueryUnitTest.java 2008-06-06 04:50:54 UTC (rev 976)
+++ branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/DatabaseSessionListQueryUnitTest.java 2008-06-06 05:41:21 UTC (rev 977)
@@ -156,6 +156,7 @@
null, // no security domain
new JotmTransactionManagerFactory(),
0, // default transaction timeout
+ 0, // default idle timeout
nodePoolFactoryClassName, // persistent
null,
stringPoolFactoryClassName, // persistent
Modified: branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/DatabaseSessionUnitTest.java
===================================================================
--- branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/DatabaseSessionUnitTest.java 2008-06-06 04:50:54 UTC (rev 976)
+++ branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/DatabaseSessionUnitTest.java 2008-06-06 05:41:21 UTC (rev 977)
@@ -514,6 +514,7 @@
null, // no security domain
new JotmTransactionManagerFactory(),
0, // default transaction timeout
+ 0, // default idle timeout
nodePoolFactoryClassName, // persistent
null,
stringPoolFactoryClassName, // persistent
Modified: branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/DatabaseUnitTest.java
===================================================================
--- branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/DatabaseUnitTest.java 2008-06-06 04:50:54 UTC (rev 976)
+++ branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/DatabaseUnitTest.java 2008-06-06 05:41:21 UTC (rev 977)
@@ -111,7 +111,7 @@
public void test1Constructor()
{
try {
- new Database(null, null, null, null, 0, null, null, null, null, null,
+ new Database(null, null, null, null, 0, 0, null, null, null, null, null,
null, null, null, null, null, null, null, null, null);
fail("Expected " + IllegalArgumentException.class);
} catch (IllegalArgumentException e) {
@@ -158,6 +158,7 @@
null, // no security domain
new JotmTransactionManagerFactory(),
0, // default transaction timeout
+ 0, // default idle timeout
"org.mulgara.store.nodepool.memory.MemoryNodePoolFactory",
null,
"org.mulgara.store.stringpool.memory.MemoryStringPoolFactory",
Modified: branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/ExternalTransactionUnitTest.java
===================================================================
--- branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/ExternalTransactionUnitTest.java 2008-06-06 04:50:54 UTC (rev 976)
+++ branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/ExternalTransactionUnitTest.java 2008-06-06 05:41:21 UTC (rev 977)
@@ -176,6 +176,7 @@
null, // no security domain
new JotmTransactionManagerFactory(),
0, // default transaction timeout
+ 0, // default idle timeout
nodePoolFactoryClassName, // persistent
new File(persistenceDirectory, "xaNodePool"),
stringPoolFactoryClassName, // persistent
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-06-06 04:50:54 UTC (rev 976)
+++ branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/MulgaraTransactionManager.java 2008-06-06 05:41:21 UTC (rev 977)
@@ -81,7 +81,9 @@
private final MulgaraExternalTransactionFactory externalFactory;
private final Timer reaperTimer;
- private LockReaper reaperTask;
+ private IdleReaper idleReaperTask;
+ private long idleTimout;
+ private LockReaper lockReaperTask;
public MulgaraTransactionManager(TransactionManagerFactory transactionManagerFactory) {
this.sessionHoldingWriteLock = null;
@@ -94,7 +96,7 @@
this.externalFactory = new MulgaraExternalTransactionFactory(this);
this.reaperTimer = new Timer("Write-lock Reaper", true);
- this.reaperTask = new LockReaper(reaperTimer, 900000); // 15 minutes inactivity.
+ this.idleReaperTask = new IdleReaper(reaperTimer, 10*1000L); // check every 10 seconds
}
@@ -130,6 +132,9 @@
}
sessionHoldingWriteLock = session;
factoryWithWriteTransaction = factory;
+ this.idleTimout = session.getIdleTimeout() > 0 ? session.getIdleTimeout() : 15*60*1000L;
+ this.lockReaperTask =
+ new LockReaper(reaperTimer, session.getTransactionTimeout() > 0 ? session.getTransactionTimeout() : 60*60*1000L);
} finally {
releaseMutex();
}
@@ -159,6 +164,7 @@
}
sessionHoldingWriteLock = null;
factoryWithWriteTransaction = null;
+ lockReaperTask.cancel();
writeLockCondition.signal();
} finally {
releaseMutex();
@@ -171,15 +177,6 @@
}
- public void setLockTimeout(long timeout) {
- acquireMutex();
- try {
- reaperTask.setTimeout(timeout);
- } finally {
- releaseMutex();
- }
- }
-
/**
* Used to replace the built in monitor to allow it to be properly released
* during potentially blocking operations. All potentially blocking
@@ -302,39 +299,25 @@
}
}
- class LockReaper extends TimerTask {
- private final long MIN_PERIOD = 30000;
-
- private Timer timer;
- protected long timeoutMillis;
-
- private boolean die;
-
- public LockReaper(Timer timer, long timeoutMillis) {
- logger.info("Lock-reaper created: " + System.identityHashCode(this));
- this.timer = timer;
- this.timeoutMillis = (timeoutMillis > MIN_PERIOD) ? timeoutMillis : MIN_PERIOD;
- this.die = false;
- schedule();
+ private class IdleReaper extends TimerTask {
+ public IdleReaper(Timer timer, long periodMillis) {
+ logger.info("Idle-reaper created: " + System.identityHashCode(this));
+ timer.schedule(this, periodMillis, periodMillis);
}
public void run() {
- logger.warn("Lock-reaper running");
+ logger.debug("Idle-reaper running");
acquireMutex();
try {
- if (die) {
- logger.info("Lock-reaper dying on request: " + System.identityHashCode(this));
- return;
- }
-
if (factoryWithWriteTransaction != null) {
long lastActive = factoryWithWriteTransaction.getLastActiveHoldingLock();
- if ((lastActive > 0) && (lastActive < System.currentTimeMillis() - timeoutMillis)) {
+ if ((lastActive > 0) && (lastActive < System.currentTimeMillis() - idleTimout)) {
logger.warn("Reclaiming writelock from inactive transaction");
factoryWithWriteTransaction.abortWriteTransaction();
} else {
- logger.debug("Transaction still active: " + lastActive + " time: " + System.currentTimeMillis() + " timeout: " + timeoutMillis);
+ if (logger.isDebugEnabled())
+ logger.debug("Transaction still active: " + lastActive + " time: " + System.currentTimeMillis() + " timeout: " + idleTimout);
}
} else {
logger.debug("No write-lock held.");
@@ -342,53 +325,38 @@
} catch (MulgaraTransactionException em) {
logger.warn("Exception thrown while reclaiming writelock from inactive transaction");
} finally {
- try {
- if (!die) {
- logger.debug("Rescheduling lock-reaper: " + System.identityHashCode(this));
- schedule();
- } else {
- logger.debug("Not rescheduling lock-reaper on request: " + System.identityHashCode(this));
- }
- } finally {
- releaseMutex();
- }
+ releaseMutex();
}
}
+ }
- public void setTimeout(long timeout) {
- acquireMutex();
- try {
- reaperTask = new LockReaper(timer, timeout);
- this.die = true;
- } finally {
- releaseMutex();
- }
+ private class LockReaper extends TimerTask {
+ private boolean die = false;
+
+ public LockReaper(Timer timer, long timeoutMillis) {
+ logger.debug("Lock-reaper created: " + System.identityHashCode(this));
+ timer.schedule(this, timeoutMillis);
}
- public long getTimeout() {
+ public boolean cancel() {
+ die = true;
+ return super.cancel();
+ }
+
+ public void run() {
acquireMutex();
+
try {
- return timeoutMillis;
+ if (die)
+ return; // we were cancelled after being scheduled but before mutex was acquired
+
+ logger.warn("Reclaiming writelock from over-extended transaction");
+ factoryWithWriteTransaction.abortWriteTransaction();
+ } catch (MulgaraTransactionException em) {
+ logger.warn("Exception thrown while reclaiming writelock from over-extended transaction", em);
} finally {
releaseMutex();
}
}
-
- private void schedule() {
- long timeout = timeoutMillis;
-
- if (factoryWithWriteTransaction != null) {
- long lastActive = factoryWithWriteTransaction.getLastActiveHoldingLock();
-
- if (lastActive > 0) {
- timeout = timeoutMillis - (System.currentTimeMillis() - lastActive);
- }
- }
-
- timeout = (timeout > MIN_PERIOD) ? timeout : MIN_PERIOD;
-
- logger.warn("Scheduling lock-reaper to run in: " + timeout + "ms");
- timer.schedule(this, timeout);
- }
}
}
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-06-06 04:50:54 UTC (rev 976)
+++ branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/MulgaraXAResourceContext.java 2008-06-06 05:41:21 UTC (rev 977)
@@ -248,7 +248,7 @@
acquireMutex();
try {
logger.info("Performing getTransactionTimeout");
- return 3600;
+ return (int) (session.getTransactionTimeout() / 1000);
} finally {
releaseMutex();
}
@@ -342,11 +342,15 @@
}
- public boolean setTransactionTimeout(int seconds) {
+ public boolean setTransactionTimeout(int seconds) throws XAException {
+ if (seconds < 0)
+ throw new XAException(XAException.XAER_INVAL);
+
acquireMutex();
try {
logger.info("Performing setTransactionTimeout");
- return false;
+ session.setTransactionTimeout(seconds * 1000L);
+ return true;
} finally {
releaseMutex();
}
Modified: branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/XADatabaseSessionUnitTest.java
===================================================================
--- branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/XADatabaseSessionUnitTest.java 2008-06-06 04:50:54 UTC (rev 976)
+++ branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/XADatabaseSessionUnitTest.java 2008-06-06 05:41:21 UTC (rev 977)
@@ -559,6 +559,7 @@
null, // no security domain
new JotmTransactionManagerFactory(),
0, // default transaction timeout
+ 0, // default idle timeout
nodePoolFactoryClassName, // persistent
new File(persistenceDirectory, "xaNodePool"),
stringPoolFactoryClassName, // persistent
Modified: branches/mgr-121-lockrecovery/src/jar/resolver-relational/java/org/mulgara/resolver/relational/RelationalResolverUnitTest.java
===================================================================
--- branches/mgr-121-lockrecovery/src/jar/resolver-relational/java/org/mulgara/resolver/relational/RelationalResolverUnitTest.java 2008-06-06 04:50:54 UTC (rev 976)
+++ branches/mgr-121-lockrecovery/src/jar/resolver-relational/java/org/mulgara/resolver/relational/RelationalResolverUnitTest.java 2008-06-06 05:41:21 UTC (rev 977)
@@ -235,6 +235,7 @@
null, // no security domain
new JotmTransactionManagerFactory(),
0, // default transaction timeout
+ 0, // default idle timeout
nodePoolFactoryClassName, // persistent
new File(persistenceDirectory, "xaNodePool"),
stringPoolFactoryClassName, // persistent
Modified: branches/mgr-121-lockrecovery/src/jar/resolver-test/java/org/mulgara/resolver/test/TestResolverUnitTest.java
===================================================================
--- branches/mgr-121-lockrecovery/src/jar/resolver-test/java/org/mulgara/resolver/test/TestResolverUnitTest.java 2008-06-06 04:50:54 UTC (rev 976)
+++ branches/mgr-121-lockrecovery/src/jar/resolver-test/java/org/mulgara/resolver/test/TestResolverUnitTest.java 2008-06-06 05:41:21 UTC (rev 977)
@@ -405,6 +405,7 @@
null, // no security domain
transactionManagerFactory,
0, // default transaction timeout
+ 0, // default idle timeout
nodePoolFactoryClassName, // persistent
new File(persistenceDirectory, "xaNodePool"),
stringPoolFactoryClassName, // persistent
Modified: branches/mgr-121-lockrecovery/src/jar/resolver-view/java/org/mulgara/resolver/view/ViewResolverUnitTest.java
===================================================================
--- branches/mgr-121-lockrecovery/src/jar/resolver-view/java/org/mulgara/resolver/view/ViewResolverUnitTest.java 2008-06-06 04:50:54 UTC (rev 976)
+++ branches/mgr-121-lockrecovery/src/jar/resolver-view/java/org/mulgara/resolver/view/ViewResolverUnitTest.java 2008-06-06 05:41:21 UTC (rev 977)
@@ -557,6 +557,7 @@
null, // no security domain
transactionManagerFactory,
0, // default transaction timeout
+ 0, // default idle timeout
nodePoolFactoryClassName, // persistent
new File(persistenceDirectory, "xaNodePool"),
stringPoolFactoryClassName, // persistent
Modified: branches/mgr-121-lockrecovery/src/jar/server-beep/java/org/mulgara/server/beep/BEEPSession.java
===================================================================
--- branches/mgr-121-lockrecovery/src/jar/server-beep/java/org/mulgara/server/beep/BEEPSession.java 2008-06-06 04:50:54 UTC (rev 976)
+++ branches/mgr-121-lockrecovery/src/jar/server-beep/java/org/mulgara/server/beep/BEEPSession.java 2008-06-06 05:41:21 UTC (rev 977)
@@ -546,4 +546,12 @@
public XAResource getReadOnlyXAResource() throws QueryException {
throw new QueryException("External transactions not implemented under Beep");
}
+
+ public void setIdleTimeout(long millis) {
+ throw new UnsupportedOperationException("Timeouts not implemented under beep.");
+ }
+
+ public void setTransactionTimeout(long millis) {
+ throw new UnsupportedOperationException("Timeouts not implemented under beep.");
+ }
}
Modified: branches/mgr-121-lockrecovery/src/jar/server-rmi/java/org/mulgara/server/rmi/RemoteSession.java
===================================================================
--- branches/mgr-121-lockrecovery/src/jar/server-rmi/java/org/mulgara/server/rmi/RemoteSession.java 2008-06-06 04:50:54 UTC (rev 976)
+++ branches/mgr-121-lockrecovery/src/jar/server-rmi/java/org/mulgara/server/rmi/RemoteSession.java 2008-06-06 05:41:21 UTC (rev 977)
@@ -308,4 +308,24 @@
*/
public RemoteXAResource getXAResource() throws QueryException, RemoteException;
public RemoteXAResource getReadOnlyXAResource() throws QueryException, RemoteException;
+
+ /**
+ * Set the idle timeout for new transactions.
+ *
+ * @param millis the number of milliseconds a transaction may be idle before being aborted,
+ * or 0 to use a default timeout.
+ * @throws QueryException
+ * @throws RemoteException
+ */
+ public void setIdleTimeout(long millis) throws QueryException, RemoteException;
+
+ /**
+ * Set the maximum duration for new transactions.
+ *
+ * @param millis the number of milliseconds a transaction may be open before being aborted,
+ * or 0 to use a default timeout.
+ * @throws QueryException
+ * @throws RemoteException
+ */
+ public void setTransactionTimeout(long millis) throws QueryException, RemoteException;
}
Modified: branches/mgr-121-lockrecovery/src/jar/server-rmi/java/org/mulgara/server/rmi/RemoteSessionWrapperSession.java
===================================================================
--- branches/mgr-121-lockrecovery/src/jar/server-rmi/java/org/mulgara/server/rmi/RemoteSessionWrapperSession.java 2008-06-06 04:50:54 UTC (rev 976)
+++ branches/mgr-121-lockrecovery/src/jar/server-rmi/java/org/mulgara/server/rmi/RemoteSessionWrapperSession.java 2008-06-06 05:41:21 UTC (rev 977)
@@ -627,4 +627,24 @@
throw new QueryException("Java RMI failure", re);
}
}
+
+ public void setIdleTimeout(long millis) throws QueryException {
+ try {
+ remoteSession.setIdleTimeout(millis);
+ resetRetries();
+ } catch (RemoteException re){
+ testRetry(re);
+ setIdleTimeout(millis);
+ }
+ }
+
+ public void setTransactionTimeout(long millis) throws QueryException {
+ try {
+ remoteSession.setTransactionTimeout(millis);
+ resetRetries();
+ } catch (RemoteException re){
+ testRetry(re);
+ setTransactionTimeout(millis);
+ }
+ }
}
Modified: branches/mgr-121-lockrecovery/src/jar/server-rmi/java/org/mulgara/server/rmi/SessionWrapperRemoteSession.java
===================================================================
--- branches/mgr-121-lockrecovery/src/jar/server-rmi/java/org/mulgara/server/rmi/SessionWrapperRemoteSession.java 2008-06-06 04:50:54 UTC (rev 976)
+++ branches/mgr-121-lockrecovery/src/jar/server-rmi/java/org/mulgara/server/rmi/SessionWrapperRemoteSession.java 2008-06-06 05:41:21 UTC (rev 977)
@@ -476,7 +476,22 @@
}
}
+ public void setIdleTimeout(long millis) throws QueryException, RemoteException {
+ try {
+ session.setIdleTimeout(millis);
+ } catch (Throwable t) {
+ throw convertToQueryException(t);
+ }
+ }
+ public void setTransactionTimeout(long millis) throws QueryException, RemoteException {
+ try {
+ session.setTransactionTimeout(millis);
+ } catch (Throwable t) {
+ throw convertToQueryException(t);
+ }
+ }
+
// Construct an exception chain that will pass over RMI.
protected Throwable mapThrowable(Throwable t) {
Throwable cause = t.getCause();
More information about the Mulgara-svn
mailing list