From 3baee4ce35e6ae0afc0581809d8ca8c66a170e20 Mon Sep 17 00:00:00 2001
From: "Brian S. O'Neill" <bronee@gmail.com>
Date: Mon, 18 Jan 2010 19:06:09 +0000
Subject: Add attach/detach notification.

---
 .../amazon/carbonado/txn/TransactionManager.java   | 25 ++++++++++++++++++++++
 .../com/amazon/carbonado/txn/TransactionScope.java | 18 ++++++++++++++++
 2 files changed, 43 insertions(+)

(limited to 'src/main')

diff --git a/src/main/java/com/amazon/carbonado/txn/TransactionManager.java b/src/main/java/com/amazon/carbonado/txn/TransactionManager.java
index 0f203aa..45a2028 100644
--- a/src/main/java/com/amazon/carbonado/txn/TransactionManager.java
+++ b/src/main/java/com/amazon/carbonado/txn/TransactionManager.java
@@ -80,6 +80,7 @@ public abstract class TransactionManager<Txn> {
         TransactionScope<Txn> scope = mLocalScope.get();
         if (scope != null) {
             scope.markDetached();
+            detachNotification(scope.getActiveTxn());
             mLocalScope.remove();
         }
         return scope;
@@ -89,6 +90,7 @@ public abstract class TransactionManager<Txn> {
     boolean removeLocalScope(TransactionScope<Txn> scope) {
         TransactionScope<Txn> existing = mLocalScope.get();
         if (existing == scope) {
+            detachNotification(scope.getActiveTxn());
             mLocalScope.remove();
             return true;
         }
@@ -99,6 +101,7 @@ public abstract class TransactionManager<Txn> {
     boolean setLocalScope(TransactionScope<Txn> scope, boolean detached) {
         TransactionScope<Txn> existing = mLocalScope.get();
         if (((existing == null || existing.isInactive()) && detached) || existing == scope) {
+            attachNotification(scope.getActiveTxn());
             mLocalScope.set(scope);
             return true;
         }
@@ -212,6 +215,28 @@ public abstract class TransactionManager<Txn> {
     protected void setForUpdate(Txn txn, boolean forUpdate) {
     }
 
+    /**
+     * Called to notify internal method that transaction is attached.
+     * The default implementation of this method does nothing. Override if
+     * using remote transactions.
+     *
+     * @param txn transaction that is attached, could be null if none exists
+     * @since 1.2.2
+     */
+    protected void attachNotification(Txn txn) {
+    }
+
+    /**
+     * Called to notify internal method that transaction is detached.
+     * The default implementation of this method does nothing. Override if
+     * using remote transactions.
+     *
+     * @param txn transaction that is dettached, could be null if none exists
+     * @since 1.2.2
+     */
+    protected void detachNotification(Txn txn) {
+    }
+
     /**
      * Commits and closes the given internal transaction.
      *
diff --git a/src/main/java/com/amazon/carbonado/txn/TransactionScope.java b/src/main/java/com/amazon/carbonado/txn/TransactionScope.java
index 4def72d..61f4b6a 100644
--- a/src/main/java/com/amazon/carbonado/txn/TransactionScope.java
+++ b/src/main/java/com/amazon/carbonado/txn/TransactionScope.java
@@ -193,6 +193,19 @@ public class TransactionScope<Txn> {
             mLock.unlock();
         }
     }
+    
+    /**
+     * Returns the implementation for the active transaction, only if it exists.
+     */
+    Txn getActiveTxn() {
+        mLock.lock();
+        try {
+            checkClosed();
+            return mActive == null ? null : mActive.getActiveTxn();
+        } finally {
+            mLock.unlock();
+        }
+    }
 
     /**
      * Returns true if an active transaction exists and it is for update.
@@ -500,6 +513,11 @@ public class TransactionScope<Txn> {
             return mTxn;
         }
 
+        // Caller must hold mLock.
+        Txn getActiveTxn() {
+            return mTxn;
+        }
+
         // Caller must hold mLock.
         private void closeCursors() throws PersistException {
             if (mCursorList != null) {
-- 
cgit v1.2.3