[Mulgara-svn] r97 - branches/xafix/src/jar/resolver/java/org/mulgara/resolver

andrae at mulgara.org andrae at mulgara.org
Mon Oct 9 11:00:26 UTC 2006


Author: andrae
Date: 2006-10-09 06:00:26 -0500 (Mon, 09 Oct 2006)
New Revision: 97

Added:
   branches/xafix/src/jar/resolver/java/org/mulgara/resolver/MulgaraTransaction.java
   branches/xafix/src/jar/resolver/java/org/mulgara/resolver/MulgaraTransactionManager.java
Log:
First: This is just an initial sketch of a new Transaction Architecture.  As 
a sketch it is not intended to compile, and indeed won't.

The driving concept behind this is:
Sessions deal with the Manager.
Operations and Answers deal with the Transaction.

Also if possible the interface to transaction should make it impossible to misuse.  Hence the use of closures passed to an execute method.



Added: branches/xafix/src/jar/resolver/java/org/mulgara/resolver/MulgaraTransaction.java
===================================================================
--- branches/xafix/src/jar/resolver/java/org/mulgara/resolver/MulgaraTransaction.java	2006-10-06 03:53:03 UTC (rev 96)
+++ branches/xafix/src/jar/resolver/java/org/mulgara/resolver/MulgaraTransaction.java	2006-10-09 11:00:26 UTC (rev 97)
@@ -0,0 +1,109 @@
+/*
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.rosenlaw.com/OSL3.0.htm
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * This file is an original work developed by Netymon Pty Ltd
+ * (http://www.netymon.com, mailto:mail at netymon.com). Portions created
+ * by Netymon Pty Ltd are Copyright (c) 2006 Netymon Pty Ltd.
+ * All Rights Reserved.
+ */
+package org.mulgara.resolver;
+
+/**
+ * Responsible for the javax.transaction.Transaction object.
+ * Responsibilities
+ * Ensuring every begin or resume is followed by either a suspend or an end.
+ * Ensuring every suspend or end is preceeded by either a begin or a resume.
+ * In conjunction with TransactionalAnswer ensuring that
+ * all calls to operations on SubqueryAnswer are preceeded by a successful resume.
+ * all calls to operations on SubqueryAnswer conclude with a suspend as the last call prior to returning to the user.
+ * Collaborates with DatabaseTransactionManager to determine when to end the transaction.
+ *
+ * @created 2006-10-06
+ *
+ * @author <a href="mailto:andrae at netymon.com">Andrae Muys</a>
+ *
+ * @version $Revision: $
+ *
+ * @modified $Date: $
+ *
+ * @maintenanceAuthor $Author: $
+ *
+ * @company <A href="mailto:mail at netymon.com">Netymon Pty Ltd</A>
+ *
+ * @copyright &copy;2006 <a href="http://www.netymon.com/">Netymon Pty Ltd</a>
+ *
+ * @licence Open Software License v3.0</a>
+ */
+public class MulgaraTransaction {
+  private final TransactionManager transactionManager;
+  private Transaction transaction;
+  private Thread currentThread;
+
+  private int inuse;
+  private int using;
+
+  public MulgaraTransaction() { 
+    inuse = 1;
+    using = 0;
+  }
+
+  public void activate() {
+    synchronized(this) {
+      if (!currentThread.equals(Thread.currentThread())) {
+        throw new MulgaraTransactionException("Concurrent access attempted to transaction");
+      }
+    }
+
+    if (inuse == 0) {
+      TransactionManager.resume(transaction);
+    }
+    inuse++;
+  }
+
+  public void deactivate() {
+    inuse--;
+    if (inuse == 0) {
+      if (using == 0) {
+        TransactionManager.commit(transaction);
+        synchronized (this) {
+          currentThread = null;
+        }
+      } else {
+        TransactionManager.suspend(transaction);
+        synchronized (this) {
+          currentThread = null;
+        }
+      }
+    }
+  }
+
+  public void reference() {
+    using++;
+  }
+
+  public void defeference() {
+    using--;
+    if (using < 0) {
+      rollback("ERROR: Transaction dereferenced more times than referenced!");
+    }
+  }
+
+  public void execute(Operation operation) {
+    activate();
+    try {
+      operation.execute(this);
+    } catch (Throwable th) {
+      implicitRollback(th);
+    } finally {
+      deactivate();
+    }
+  }
+}

Added: branches/xafix/src/jar/resolver/java/org/mulgara/resolver/MulgaraTransactionManager.java
===================================================================
--- branches/xafix/src/jar/resolver/java/org/mulgara/resolver/MulgaraTransactionManager.java	2006-10-06 03:53:03 UTC (rev 96)
+++ branches/xafix/src/jar/resolver/java/org/mulgara/resolver/MulgaraTransactionManager.java	2006-10-09 11:00:26 UTC (rev 97)
@@ -0,0 +1,150 @@
+/*
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.rosenlaw.com/OSL3.0.htm
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * This file is an original work developed by Netymon Pty Ltd
+ * (http://www.netymon.com, mailto:mail at netymon.com). Portions created
+ * by Netymon Pty Ltd are Copyright (c) 2006 Netymon Pty Ltd.
+ * All Rights Reserved.
+ */
+
+package org.mulgara.resolver;
+
+/**
+ * Manages transactions within Mulgara.
+ *
+ * see http://mulgara.org/confluence/display/dev/Transaction+Architecture
+ *
+ * Maintains association between Answer's and TransactionContext's.
+ * Manages tracking the ownership of the write-lock.
+ * Maintains the write-queue and any timeout algorithm desired.
+ * Provides new/existing TransactionContext's to DatabaseSession on request.
+ *    Note: Returns new context unless Session is currently in a User Demarcated Transaction.
+ * 
+ *
+ * @created 2006-10-06
+ *
+ * @author <a href="mailto:andrae at netymon.com">Andrae Muys</a>
+ *
+ * @version $Revision: $
+ *
+ * @modified $Date: $
+ *
+ * @maintenanceAuthor $Author: $
+ *
+ * @company <A href="mailto:mail at netymon.com">Netymon Pty Ltd</A>
+ *
+ * @copyright &copy;2006 <a href="http://www.netymon.com/">Netymon Pty Ltd</a>
+ *
+ * @licence Open Software License v3.0</a>
+ */
+
+public class MulgaraTransactionManager {
+  // Write lock is associated with a session.
+  private Session currentWritingSession;
+  private MulgaraTransaction writeTransaction;
+  private Object writeLockMutex = new Object();
+
+  private Map threadMap;
+  private Map answerMap;
+
+  public MulgaraTransactionManager() {
+  }
+
+  /**
+   * Allows DatabaseSession to initiate/obtain a transaction.
+   * <ul>
+   * <li>If the Session holds the write lock, return the current Write-Transaction.</li>
+   * <li>If the Session does not hold the write lock and requests a read-only transaction,
+   *     create a new ro-transaction object and return it.</li>
+   * <li>If the Session does not hold the write lock and requests a read-write transaction,
+   *     obtain the write-lock, create a new transaction object and return it.</li>
+   * </ul>
+   */
+  public MulgaraTransaction getTransaction(Session session, boolean write) {
+    synchronized (writeLockMutex) {
+      if (session == currentWritingSession) {
+        return writeTransaction;
+      } 
+    }
+    if (!write) {
+      return new MulgaraTransaction(this);
+    } else {
+      obtainWriteLock(session);
+      writeTransaction.reference();
+      return writeTransaction;
+    }
+  }
+
+  protected void obtainWriteLock(Session session) {
+    synchronized (writeLockMutex) {
+      while (currentWritingSession != null) {
+        writeLockMutex.wait();
+      }
+      currentWritingSession = session;
+    }
+
+    writeTransaction = new MulgaraTransaction(this);
+  }
+
+  protected void releaseWriteLock() {
+    synchronized (writeLockMutex) {
+      currentWritingSession = null;
+      writeTransaction = null;
+      writeLockMutex.notify();
+    }
+  }
+
+  public MulgaraTransaction getTransaction(Answer answer) throws MulgaraTransactionException {
+    synchronized (answerMap) {
+      MulgaraTransaction xa = (MulgaraTransaction)answerMap.get(answer);
+      if (xa != null) {
+        return xa;
+      } else {
+        throw new MulgaraTransactionException("Unable to find transaction for answer: " + answer);
+      }
+    }
+  }
+
+
+  public MulgaraTransaction getTransaction() throws MulgaraTransactionException {
+    synchronized(threadMap) {
+      MulgaraTransaction xa = (MulgaraTransaction)threadMap.get(Thread.currentThread());
+      if (xa != null) {
+        return xa;
+      } else {
+        throw new MulgaraTransactionException("Activated exception not found for current thread");
+      }
+    }
+  }
+
+  public void commit(Session session) {
+    synchronized (writeLockMutex) {
+      setAutoCommit(true);
+      setAutoCommit(false);
+    }
+  }
+
+  /**
+   * This is an explicit, user-specified rollback.
+   * This needs to be distinguished from an implicit rollback triggered by failure.
+   */
+  public void rollback(Session) {
+
+  }
+
+  public void setAutocommit(Session session, boolean acommit) {
+    synchronized (writeLockMutex) {
+    }
+  }
+
+  public close() {
+  }
+}




More information about the Mulgara-svn mailing list