Author: dblevins
Date: Mon Feb 22 02:11:40 2010
New Revision: 912464
URL: http://svn.apache.org/viewvc?rev=912464&view=rev
Log:
Filled out the example to show various ways to rollback a transaction
Added:
openejb/trunk/openejb3/examples/transaction-rollback/src/main/java/org/superbiz/txrollback/CustomRuntimeException.java
(with props)
Modified:
openejb/trunk/openejb3/examples/transaction-rollback/src/main/java/org/superbiz/txrollback/Movies.java
openejb/trunk/openejb3/examples/transaction-rollback/src/main/java/org/superbiz/txrollback/MoviesImpl.java
openejb/trunk/openejb3/examples/transaction-rollback/src/test/java/org/superbiz/txrollback/MoviesTest.java
Added:
openejb/trunk/openejb3/examples/transaction-rollback/src/main/java/org/superbiz/txrollback/CustomRuntimeException.java
URL:
http://svn.apache.org/viewvc/openejb/trunk/openejb3/examples/transaction-rollback/src/main/java/org/superbiz/txrollback/CustomRuntimeException.java?rev=912464&view=auto
==============================================================================
---
openejb/trunk/openejb3/examples/transaction-rollback/src/main/java/org/superbiz/txrollback/CustomRuntimeException.java
(added)
+++
openejb/trunk/openejb3/examples/transaction-rollback/src/main/java/org/superbiz/txrollback/CustomRuntimeException.java
Mon Feb 22 02:11:40 2010
@@ -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.superbiz.txrollback;
+
+import javax.ejb.ApplicationException;
+
+...@applicationexception
+public class CustomRuntimeException extends RuntimeException {
+
+ public CustomRuntimeException() {
+ }
+
+ public CustomRuntimeException(String s) {
+ super(s);
+ }
+
+ public CustomRuntimeException(String s, Throwable throwable) {
+ super(s, throwable);
+ }
+
+ public CustomRuntimeException(Throwable throwable) {
+ super(throwable);
+ }
+}
Propchange:
openejb/trunk/openejb3/examples/transaction-rollback/src/main/java/org/superbiz/txrollback/CustomRuntimeException.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified:
openejb/trunk/openejb3/examples/transaction-rollback/src/main/java/org/superbiz/txrollback/Movies.java
URL:
http://svn.apache.org/viewvc/openejb/trunk/openejb3/examples/transaction-rollback/src/main/java/org/superbiz/txrollback/Movies.java?rev=912464&r1=912463&r2=912464&view=diff
==============================================================================
---
openejb/trunk/openejb3/examples/transaction-rollback/src/main/java/org/superbiz/txrollback/Movies.java
(original)
+++
openejb/trunk/openejb3/examples/transaction-rollback/src/main/java/org/superbiz/txrollback/Movies.java
Mon Feb 22 02:11:40 2010
@@ -24,4 +24,10 @@
void deleteMovie(Movie movie) throws Exception;
List<Movie> getMovies() throws Exception;
+
+ void callSetRollbackOnly();
+
+ void throwUncheckedException();
+
+ void throwApplicationException();
}
Modified:
openejb/trunk/openejb3/examples/transaction-rollback/src/main/java/org/superbiz/txrollback/MoviesImpl.java
URL:
http://svn.apache.org/viewvc/openejb/trunk/openejb3/examples/transaction-rollback/src/main/java/org/superbiz/txrollback/MoviesImpl.java?rev=912464&r1=912463&r2=912464&view=diff
==============================================================================
---
openejb/trunk/openejb3/examples/transaction-rollback/src/main/java/org/superbiz/txrollback/MoviesImpl.java
(original)
+++
openejb/trunk/openejb3/examples/transaction-rollback/src/main/java/org/superbiz/txrollback/MoviesImpl.java
Mon Feb 22 02:11:40 2010
@@ -17,19 +17,25 @@
package org.superbiz.txrollback;
import javax.ejb.Stateful;
+import javax.ejb.SessionContext;
+import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceContextType;
import javax.persistence.Query;
+import javax.annotation.Resource;
import java.util.List;
//START SNIPPET: code
-...@stateful(name = "Movies")
+...@stateless(name = "Movies")
public class MoviesImpl implements Movies {
@PersistenceContext(unitName = "movie-unit", type =
PersistenceContextType.TRANSACTION)
private EntityManager entityManager;
+ @Resource
+ private SessionContext sessionContext;
+
public void addMovie(Movie movie) throws Exception {
entityManager.persist(movie);
}
@@ -42,4 +48,16 @@
Query query = entityManager.createQuery("SELECT m from Movie as m");
return query.getResultList();
}
+
+ public void callSetRollbackOnly() {
+ sessionContext.setRollbackOnly();
+ }
+
+ public void throwUncheckedException() {
+ throw new RuntimeException("Throwing unchecked exceptions will
rollback a transaction");
+ }
+
+ public void throwApplicationException() {
+ throw new CustomRuntimeException("This is marked
@ApplicationException, so no TX rollback");
+ }
}
Modified:
openejb/trunk/openejb3/examples/transaction-rollback/src/test/java/org/superbiz/txrollback/MoviesTest.java
URL:
http://svn.apache.org/viewvc/openejb/trunk/openejb3/examples/transaction-rollback/src/test/java/org/superbiz/txrollback/MoviesTest.java?rev=912464&r1=912463&r2=912464&view=diff
==============================================================================
---
openejb/trunk/openejb3/examples/transaction-rollback/src/test/java/org/superbiz/txrollback/MoviesTest.java
(original)
+++
openejb/trunk/openejb3/examples/transaction-rollback/src/test/java/org/superbiz/txrollback/MoviesTest.java
Mon Feb 22 02:11:40 2010
@@ -26,6 +26,10 @@
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.transaction.UserTransaction;
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.RollbackException;
+import javax.transaction.SystemException;
import java.util.List;
import java.util.Properties;
@@ -62,6 +66,13 @@
initialContext.close();
}
+ /**
+ * Standard successful transaction scenario. The data created inside
+ * the transaction is visible after the transaction completes.
+ *
+ * Note that UserTransaction is only usable by Bean-Managed Transaction
+ * beans, which can be specified with @TransactionManagement(BEAN)
+ */
public void testCommit() throws Exception {
userTransaction.begin();
@@ -84,7 +95,11 @@
}
- public void testRollback() throws Exception {
+ /**
+ * Standard transaction rollback scenario. The data created inside
+ * the transaction is not visible after the transaction completes.
+ */
+ public void testUserTransactionRollback() throws Exception {
userTransaction.begin();
@@ -106,5 +121,110 @@
}
+ /**
+ * Transaction is marked for rollback inside the bean via
+ * calling the javax.ejb.SessionContext.setRollbackOnly() method
+ *
+ * This is the cleanest way to make a transaction rollback.
+ */
+ public void testMarkedRollback() throws Exception {
+
+ userTransaction.begin();
+
+ try {
+ entityManager.persist(new Movie("Quentin Tarantino", "Reservoir
Dogs", 1992));
+ entityManager.persist(new Movie("Joel Coen", "Fargo", 1996));
+ entityManager.persist(new Movie("Joel Coen", "The Big Lebowski",
1998));
+
+ List<Movie> list = movies.getMovies();
+ assertEquals("List.size()", 3, list.size());
+
+ movies.callSetRollbackOnly();
+ } finally {
+ try {
+ userTransaction.commit();
+ fail("A RollbackException should have been thrown");
+ } catch (RollbackException e) {
+ // Pass
+ }
+ }
+
+ // Transaction was rolled back
+ List<Movie> list = movies.getMovies();
+ assertEquals("List.size()", 0, list.size());
+
+ }
+
+ /**
+ * Throwing an unchecked exception from a bean will cause
+ * the container to call setRollbackOnly() and discard the
+ * bean instance from further use without calling any @PreDestroy
+ * methods on the bean instance.
+ */
+ public void testExceptionBasedRollback() throws Exception {
+
+ userTransaction.begin();
+
+ try {
+ entityManager.persist(new Movie("Quentin Tarantino", "Reservoir
Dogs", 1992));
+ entityManager.persist(new Movie("Joel Coen", "Fargo", 1996));
+ entityManager.persist(new Movie("Joel Coen", "The Big Lebowski",
1998));
+
+ List<Movie> list = movies.getMovies();
+ assertEquals("List.size()", 3, list.size());
+
+ try {
+ movies.throwUncheckedException();
+ } catch (RuntimeException e) {
+ // Good, this will cause the tx to rollback
+ }
+ } finally {
+ try {
+ userTransaction.commit();
+ fail("A RollbackException should have been thrown");
+ } catch (RollbackException e) {
+ // Pass
+ }
+ }
+
+ // Transaction was rolled back
+ List<Movie> list = movies.getMovies();
+ assertEquals("List.size()", 0, list.size());
+
+ }
+
+ /**
+ * It is still possible to throw unchecked (runtime) exceptions
+ * without dooming the transaction by marking the exception
+ * with the @ApplicationException annotation or in the ejb-jar.xml
+ * deployment descriptor via the <application-exception> tag
+ */
+ public void testCommit2() throws Exception {
+
+ userTransaction.begin();
+
+ try {
+ entityManager.persist(new Movie("Quentin Tarantino", "Reservoir
Dogs", 1992));
+ entityManager.persist(new Movie("Joel Coen", "Fargo", 1996));
+ entityManager.persist(new Movie("Joel Coen", "The Big Lebowski",
1998));
+
+ List<Movie> list = movies.getMovies();
+ assertEquals("List.size()", 3, list.size());
+
+ try {
+ movies.throwApplicationException();
+ } catch (RuntimeException e) {
+ // This will *not* cause the tx to rollback
+ // because it is marked as an @ApplicationException
+ }
+ } finally {
+ userTransaction.commit();
+ }
+
+ // Transaction was committed
+ List<Movie> list = movies.getMovies();
+ assertEquals("List.size()", 3, list.size());
+
+ }
}
//END SNIPPET: code