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);
+ }
+ }
+}