Author: aadamchik
Date: Thu Dec  6 12:01:03 2012
New Revision: 1417809

URL: http://svn.apache.org/viewvc?rev=1417809&view=rev
Log:
CAY-1778 TransactionManager to simplify user-managed transactions

Added:
    
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/tx/
    
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/tx/DefaultTransactionManager.java
    
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/tx/TransactionManager.java
    
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/tx/TransactionalOperation.java
    
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/tx/
    
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/tx/DefaultTransactionManagerTest.java
Modified:
    cayenne/main/trunk/docs/doc/src/main/resources/RELEASE-NOTES.txt
    
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/configuration/server/ServerModule.java
    
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/configuration/server/ServerRuntime.java

Modified: cayenne/main/trunk/docs/doc/src/main/resources/RELEASE-NOTES.txt
URL: 
http://svn.apache.org/viewvc/cayenne/main/trunk/docs/doc/src/main/resources/RELEASE-NOTES.txt?rev=1417809&r1=1417808&r2=1417809&view=diff
==============================================================================
--- cayenne/main/trunk/docs/doc/src/main/resources/RELEASE-NOTES.txt (original)
+++ cayenne/main/trunk/docs/doc/src/main/resources/RELEASE-NOTES.txt Thu Dec  6 
12:01:03 2012
@@ -36,6 +36,7 @@ CAY-1768 cdbimport improvements: DataMap
 CAY-1769 cdbimport improvements: meaningfulPk flag must be turned into a 
pattern
 CAY-1771 cdbimport improvements: "usePrimitives" flag
 CAY-1772 Real support for DbEntity catalogs
+CAY-1778 TransactionManager to simplify user-managed transactions 
 
 Bug Fixes:
 

Modified: 
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/configuration/server/ServerModule.java
URL: 
http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/configuration/server/ServerModule.java?rev=1417809&r1=1417808&r2=1417809&view=diff
==============================================================================
--- 
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/configuration/server/ServerModule.java
 (original)
+++ 
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/configuration/server/ServerModule.java
 Thu Dec  6 12:01:03 2012
@@ -89,6 +89,8 @@ import org.apache.cayenne.log.JdbcEventL
 import org.apache.cayenne.map.EntitySorter;
 import org.apache.cayenne.resource.ClassLoaderResourceLocator;
 import org.apache.cayenne.resource.ResourceLocator;
+import org.apache.cayenne.tx.DefaultTransactionManager;
+import org.apache.cayenne.tx.TransactionManager;
 
 /**
  * A DI module containing all Cayenne server runtime configuration.
@@ -237,5 +239,7 @@ public class ServerModule implements Mod
 
         // a default ObjectStoreFactory used to create ObjectStores for 
contexts
         
binder.bind(ObjectStoreFactory.class).to(DefaultObjectStoreFactory.class);
+        
+        
binder.bind(TransactionManager.class).to(DefaultTransactionManager.class);
     }
 }

Modified: 
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/configuration/server/ServerRuntime.java
URL: 
http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/configuration/server/ServerRuntime.java?rev=1417809&r1=1417808&r2=1417809&view=diff
==============================================================================
--- 
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/configuration/server/ServerRuntime.java
 (original)
+++ 
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/configuration/server/ServerRuntime.java
 Thu Dec  6 12:01:03 2012
@@ -27,6 +27,7 @@ import org.apache.cayenne.access.DataNod
 import org.apache.cayenne.configuration.CayenneRuntime;
 import org.apache.cayenne.configuration.rop.client.ClientRuntime;
 import org.apache.cayenne.di.Module;
+import org.apache.cayenne.tx.TransactionManager;
 
 /**
  * An object representing Cayenne server-stack that connects directly to the 
database via
@@ -62,6 +63,13 @@ public class ServerRuntime extends Cayen
     public ServerRuntime(String[] configurationLocations, Module... 
extraModules) {
         super(mergeModules(mainModule(configurationLocations), extraModules));
     }
+    
+    /**
+     * @since 3.2
+     */
+    public TransactionManager getTransactionManager() {
+        return injector.getInstance(TransactionManager.class);
+    }
 
     /**
      * Returns the main runtime DataDomain. Note that by default the returned 
DataDomain

Added: 
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/tx/DefaultTransactionManager.java
URL: 
http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/tx/DefaultTransactionManager.java?rev=1417809&view=auto
==============================================================================
--- 
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/tx/DefaultTransactionManager.java
 (added)
+++ 
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/tx/DefaultTransactionManager.java
 Thu Dec  6 12:01:03 2012
@@ -0,0 +1,66 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+package org.apache.cayenne.tx;
+
+import org.apache.cayenne.CayenneRuntimeException;
+import org.apache.cayenne.access.Transaction;
+import org.apache.cayenne.configuration.server.ServerRuntime;
+import org.apache.cayenne.di.Inject;
+
+/**
+ * @since 3.2
+ */
+public class DefaultTransactionManager implements TransactionManager {
+
+    private ServerRuntime runtime;
+
+    public DefaultTransactionManager(@Inject ServerRuntime runtime) {
+        this.runtime = runtime;
+    }
+
+    public <T> T performInTransaction(TransactionalOperation<T> op) {
+
+        // join existing tx if it is in progress... in such case do not try to
+        // commit or roll it back
+        Transaction currentTx = Transaction.getThreadTransaction();
+        if (currentTx != null) {
+            return op.perform(runtime);
+        }
+
+        // start a new tx and manage it till the end
+        Transaction tx = runtime.getDataDomain().createTransaction();
+        Transaction.bindThreadTransaction(tx);
+        try {
+            return op.perform(runtime);
+        } catch (Exception ex) {
+            tx.setRollbackOnly();
+            throw new CayenneRuntimeException(ex);
+        } finally {
+            Transaction.bindThreadTransaction(null);
+
+            if (tx.getStatus() == Transaction.STATUS_MARKED_ROLLEDBACK) {
+                try {
+                    tx.rollback();
+                } catch (Exception rollbackEx) {
+                }
+            }
+        }
+    }
+
+}

Added: 
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/tx/TransactionManager.java
URL: 
http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/tx/TransactionManager.java?rev=1417809&view=auto
==============================================================================
--- 
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/tx/TransactionManager.java
 (added)
+++ 
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/tx/TransactionManager.java
 Thu Dec  6 12:01:03 2012
@@ -0,0 +1,38 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+package org.apache.cayenne.tx;
+
+import org.apache.cayenne.configuration.CayenneRuntime;
+
+/**
+ * An optional utility service that simplifies wrapping multiple operations in
+ * transactions. Users only rarely need to invoke it directly, as all standard
+ * Cayenne operations are managing their own transactions internally.
+ * 
+ * @since 3.2
+ */
+public interface TransactionManager {
+
+    /**
+     * Starts a new transaction (or joins an existing one) calling
+     * {@link TransactionalOperation#perform(CayenneRuntime)}, and then
+     * committing or rolling back the transaction. Frees the user
+     */
+    <T> T performInTransaction(TransactionalOperation<T> op);
+}

Added: 
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/tx/TransactionalOperation.java
URL: 
http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/tx/TransactionalOperation.java?rev=1417809&view=auto
==============================================================================
--- 
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/tx/TransactionalOperation.java
 (added)
+++ 
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/tx/TransactionalOperation.java
 Thu Dec  6 12:01:03 2012
@@ -0,0 +1,34 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+package org.apache.cayenne.tx;
+
+import org.apache.cayenne.configuration.CayenneRuntime;
+
+/**
+ * @since 3.2
+ */
+public interface TransactionalOperation<T> {
+
+    /**
+     * A callback method that {@link TransactionManager} invokes,
+     * {@link TransactionManager} will wrap this method call in a single
+     * thread-bound transaction.
+     */
+    T perform(CayenneRuntime runtime);
+}

Added: 
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/tx/DefaultTransactionManagerTest.java
URL: 
http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/tx/DefaultTransactionManagerTest.java?rev=1417809&view=auto
==============================================================================
--- 
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/tx/DefaultTransactionManagerTest.java
 (added)
+++ 
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/tx/DefaultTransactionManagerTest.java
 Thu Dec  6 12:01:03 2012
@@ -0,0 +1,70 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+package org.apache.cayenne.tx;
+
+import static org.mockito.Mockito.mock;
+
+import org.apache.cayenne.access.Transaction;
+import org.apache.cayenne.configuration.CayenneRuntime;
+import org.apache.cayenne.configuration.server.ServerRuntime;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.unit.di.server.ServerCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+
+@UseServerRuntime(ServerCase.TESTMAP_PROJECT)
+public class DefaultTransactionManagerTest extends ServerCase {
+
+    @Inject
+    private ServerRuntime runtime;
+
+    public void testPerformInTransaction_NoTx() {
+        DefaultTransactionManager txManager = new 
DefaultTransactionManager(runtime);
+
+        final Object expectedResult = new Object();
+        Object result = txManager.performInTransaction(new 
TransactionalOperation<Object>() {
+            public Object perform(CayenneRuntime runtime) {
+                assertNotNull(Transaction.getThreadTransaction());
+                return expectedResult;
+            }
+        });
+
+        assertSame(expectedResult, result);
+    }
+
+    public void testPerformInTransaction_ExistingTx() {
+        DefaultTransactionManager txManager = new 
DefaultTransactionManager(runtime);
+
+        final Transaction tx = mock(Transaction.class);
+        Transaction.bindThreadTransaction(tx);
+        try {
+
+            final Object expectedResult = new Object();
+            Object result = txManager.performInTransaction(new 
TransactionalOperation<Object>() {
+                public Object perform(CayenneRuntime runtime) {
+                    assertSame(tx, Transaction.getThreadTransaction());
+                    return expectedResult;
+                }
+            });
+
+            assertSame(expectedResult, result);
+        } finally {
+            Transaction.bindThreadTransaction(null);
+        }
+    }
+}


Reply via email to