Commit 7fb2f7419903f224fe834664005827b4db4ecd28
Exists in
master
Merge branch 'master' of git@github.com:demoiselle/framework.git
Showing
13 changed files
with
333 additions
and
41 deletions
Show diff stats
impl/core/src/main/java/br/gov/frameworkdemoiselle/transaction/Transaction.java
@@ -51,6 +51,7 @@ public interface Transaction extends Serializable { | @@ -51,6 +51,7 @@ public interface Transaction extends Serializable { | ||
51 | * Indicates whether the given transaction is still active. | 51 | * Indicates whether the given transaction is still active. |
52 | * | 52 | * |
53 | * @return a boolean | 53 | * @return a boolean |
54 | + * @throws TransactionException if an unexpected error occurs | ||
54 | */ | 55 | */ |
55 | boolean isActive(); | 56 | boolean isActive(); |
56 | 57 | ||
@@ -58,29 +59,38 @@ public interface Transaction extends Serializable { | @@ -58,29 +59,38 @@ public interface Transaction extends Serializable { | ||
58 | * Indicates whether the given transaction is already marked to be rolled back. | 59 | * Indicates whether the given transaction is already marked to be rolled back. |
59 | * | 60 | * |
60 | * @return a boolean | 61 | * @return a boolean |
62 | + * @throws TransactionException if an unexpected error occurs | ||
61 | */ | 63 | */ |
62 | boolean isMarkedRollback(); | 64 | boolean isMarkedRollback(); |
63 | 65 | ||
64 | /** | 66 | /** |
65 | * Create a new transaction and associate it with the current thread. | 67 | * Create a new transaction and associate it with the current thread. |
68 | + * | ||
69 | + * @throws TransactionException if the transaction can't be started | ||
66 | */ | 70 | */ |
67 | void begin(); | 71 | void begin(); |
68 | 72 | ||
69 | /** | 73 | /** |
70 | * Complete the transaction associated with the current thread. When this method completes, the thread is no longer | 74 | * Complete the transaction associated with the current thread. When this method completes, the thread is no longer |
71 | * associated with a transaction. | 75 | * associated with a transaction. |
76 | + * | ||
77 | + * @throws TransactionException if the transaction can't be commited | ||
72 | */ | 78 | */ |
73 | void commit(); | 79 | void commit(); |
74 | 80 | ||
75 | /** | 81 | /** |
76 | * Roll back the transaction associated with the current thread. When this method completes, the thread is no longer | 82 | * Roll back the transaction associated with the current thread. When this method completes, the thread is no longer |
77 | * associated with a transaction. | 83 | * associated with a transaction. |
84 | + * | ||
85 | + * @throws TransactionException if the transaction can't be rolled back | ||
78 | */ | 86 | */ |
79 | void rollback(); | 87 | void rollback(); |
80 | 88 | ||
81 | /** | 89 | /** |
82 | * Modify the transaction associated with the current thread such that the only possible outcome of the transaction | 90 | * Modify the transaction associated with the current thread such that the only possible outcome of the transaction |
83 | * is to roll back the transaction. | 91 | * is to roll back the transaction. |
92 | + * | ||
93 | + * @throws TransactionException if an unexpected error occurs | ||
84 | */ | 94 | */ |
85 | void setRollbackOnly(); | 95 | void setRollbackOnly(); |
86 | } | 96 | } |
impl/core/src/main/java/br/gov/frameworkdemoiselle/transaction/TransactionException.java
0 → 100644
@@ -0,0 +1,64 @@ | @@ -0,0 +1,64 @@ | ||
1 | +/* | ||
2 | + * Demoiselle Framework | ||
3 | + * Copyright (C) 2010 SERPRO | ||
4 | + * ---------------------------------------------------------------------------- | ||
5 | + * This file is part of Demoiselle Framework. | ||
6 | + * | ||
7 | + * Demoiselle Framework is free software; you can redistribute it and/or | ||
8 | + * modify it under the terms of the GNU Lesser General Public License version 3 | ||
9 | + * as published by the Free Software Foundation. | ||
10 | + * | ||
11 | + * This program is distributed in the hope that it will be useful, | ||
12 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | + * GNU General Public License for more details. | ||
15 | + * | ||
16 | + * You should have received a copy of the GNU Lesser General Public License version 3 | ||
17 | + * along with this program; if not, see <http://www.gnu.org/licenses/> | ||
18 | + * or write to the Free Software Foundation, Inc., 51 Franklin Street, | ||
19 | + * Fifth Floor, Boston, MA 02110-1301, USA. | ||
20 | + * ---------------------------------------------------------------------------- | ||
21 | + * Este arquivo é parte do Framework Demoiselle. | ||
22 | + * | ||
23 | + * O Framework Demoiselle é um software livre; você pode redistribuí-lo e/ou | ||
24 | + * modificá-lo dentro dos termos da GNU LGPL versão 3 como publicada pela Fundação | ||
25 | + * do Software Livre (FSF). | ||
26 | + * | ||
27 | + * Este programa é distribuído na esperança que possa ser útil, mas SEM NENHUMA | ||
28 | + * GARANTIA; sem uma garantia implícita de ADEQUAÇÃO a qualquer MERCADO ou | ||
29 | + * APLICAÇÃO EM PARTICULAR. Veja a Licença Pública Geral GNU/LGPL em português | ||
30 | + * para maiores detalhes. | ||
31 | + * | ||
32 | + * Você deve ter recebido uma cópia da GNU LGPL versão 3, sob o título | ||
33 | + * "LICENCA.txt", junto com esse programa. Se não, acesse <http://www.gnu.org/licenses/> | ||
34 | + * ou escreva para a Fundação do Software Livre (FSF) Inc., | ||
35 | + * 51 Franklin St, Fifth Floor, Boston, MA 02111-1301, USA. | ||
36 | + */ | ||
37 | +package br.gov.frameworkdemoiselle.transaction; | ||
38 | + | ||
39 | +import br.gov.frameworkdemoiselle.DemoiselleException; | ||
40 | + | ||
41 | + | ||
42 | +/** | ||
43 | + * Represents exceptions that occur during framework managed transactions. A transaction | ||
44 | + * exception will be thrown when a transaction can't be started, commited or rolled back. | ||
45 | + * | ||
46 | + * @author serpro | ||
47 | + * | ||
48 | + */ | ||
49 | +public class TransactionException extends DemoiselleException { | ||
50 | + | ||
51 | + private static final long serialVersionUID = 1L; | ||
52 | + | ||
53 | + public TransactionException(String message, Throwable cause) { | ||
54 | + super(message, cause); | ||
55 | + } | ||
56 | + | ||
57 | + public TransactionException(Throwable cause) { | ||
58 | + super(cause); | ||
59 | + } | ||
60 | + | ||
61 | + public TransactionException(String message) { | ||
62 | + super(message); | ||
63 | + } | ||
64 | +} |
impl/extension/jdbc/src/main/java/br/gov/frameworkdemoiselle/internal/producer/ConnectionProducer.java
@@ -129,6 +129,7 @@ public class ConnectionProducer implements Serializable { | @@ -129,6 +129,7 @@ public class ConnectionProducer implements Serializable { | ||
129 | } else { | 129 | } else { |
130 | try { | 130 | try { |
131 | connection = producer.create(name).getConnection(); | 131 | connection = producer.create(name).getConnection(); |
132 | + setTransactionIsolationLevel(connection); | ||
132 | disableAutoCommit(connection); | 133 | disableAutoCommit(connection); |
133 | 134 | ||
134 | cache.put(name, connection); | 135 | cache.put(name, connection); |
@@ -143,6 +144,14 @@ public class ConnectionProducer implements Serializable { | @@ -143,6 +144,14 @@ public class ConnectionProducer implements Serializable { | ||
143 | return connection; | 144 | return connection; |
144 | } | 145 | } |
145 | 146 | ||
147 | + private void setTransactionIsolationLevel(Connection connection) { | ||
148 | + try { | ||
149 | + connection.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED); | ||
150 | + } catch (SQLException cause) { | ||
151 | + getLogger().debug(getBundle().getString("set-autocommit-failed")); | ||
152 | + } | ||
153 | + } | ||
154 | + | ||
146 | private void disableAutoCommit(Connection connection) { | 155 | private void disableAutoCommit(Connection connection) { |
147 | try { | 156 | try { |
148 | connection.setAutoCommit(false); | 157 | connection.setAutoCommit(false); |
impl/extension/jdbc/src/main/java/br/gov/frameworkdemoiselle/transaction/JDBCTransaction.java
@@ -94,7 +94,7 @@ public class JDBCTransaction implements Transaction { | @@ -94,7 +94,7 @@ public class JDBCTransaction implements Transaction { | ||
94 | status = getProducer().getStatus(connection); | 94 | status = getProducer().getStatus(connection); |
95 | status.setActive(false); | 95 | status.setActive(false); |
96 | } catch (Exception cause) { | 96 | } catch (Exception cause) { |
97 | - throw new DemoiselleException(cause); | 97 | + throw new TransactionException(cause); |
98 | } | 98 | } |
99 | } | 99 | } |
100 | } | 100 | } |
@@ -112,7 +112,7 @@ public class JDBCTransaction implements Transaction { | @@ -112,7 +112,7 @@ public class JDBCTransaction implements Transaction { | ||
112 | status = getProducer().getStatus(connection); | 112 | status = getProducer().getStatus(connection); |
113 | status.setActive(false); | 113 | status.setActive(false); |
114 | } catch (Exception cause) { | 114 | } catch (Exception cause) { |
115 | - throw new DemoiselleException(cause); | 115 | + throw new TransactionException(cause); |
116 | } | 116 | } |
117 | } | 117 | } |
118 | } | 118 | } |
impl/extension/jpa/src/main/java/br/gov/frameworkdemoiselle/transaction/JPATransaction.java
@@ -46,6 +46,8 @@ import javax.persistence.EntityTransaction; | @@ -46,6 +46,8 @@ import javax.persistence.EntityTransaction; | ||
46 | import br.gov.frameworkdemoiselle.annotation.Priority; | 46 | import br.gov.frameworkdemoiselle.annotation.Priority; |
47 | import br.gov.frameworkdemoiselle.internal.producer.EntityManagerProducer; | 47 | import br.gov.frameworkdemoiselle.internal.producer.EntityManagerProducer; |
48 | import br.gov.frameworkdemoiselle.util.Beans; | 48 | import br.gov.frameworkdemoiselle.util.Beans; |
49 | +import br.gov.frameworkdemoiselle.util.NameQualifier; | ||
50 | +import br.gov.frameworkdemoiselle.util.ResourceBundle; | ||
49 | 51 | ||
50 | /** | 52 | /** |
51 | * Represents the strategy destinated to manage JPA transactions. | 53 | * Represents the strategy destinated to manage JPA transactions. |
@@ -59,6 +61,8 @@ public class JPATransaction implements Transaction { | @@ -59,6 +61,8 @@ public class JPATransaction implements Transaction { | ||
59 | private static final long serialVersionUID = 1L; | 61 | private static final long serialVersionUID = 1L; |
60 | 62 | ||
61 | private EntityManagerProducer producer; | 63 | private EntityManagerProducer producer; |
64 | + | ||
65 | + private ResourceBundle bundle; | ||
62 | 66 | ||
63 | private EntityManagerProducer getProducer() { | 67 | private EntityManagerProducer getProducer() { |
64 | if (producer == null) { | 68 | if (producer == null) { |
@@ -67,6 +71,14 @@ public class JPATransaction implements Transaction { | @@ -67,6 +71,14 @@ public class JPATransaction implements Transaction { | ||
67 | 71 | ||
68 | return producer; | 72 | return producer; |
69 | } | 73 | } |
74 | + | ||
75 | + private ResourceBundle getBundle() { | ||
76 | + if (bundle==null) { | ||
77 | + bundle = Beans.getReference(ResourceBundle.class , new NameQualifier("demoiselle-jpa-bundle")); | ||
78 | + } | ||
79 | + | ||
80 | + return bundle; | ||
81 | + } | ||
70 | 82 | ||
71 | public Collection<EntityManager> getDelegate() { | 83 | public Collection<EntityManager> getDelegate() { |
72 | return getProducer().getCache().values(); | 84 | return getProducer().getCache().values(); |
@@ -75,23 +87,58 @@ public class JPATransaction implements Transaction { | @@ -75,23 +87,58 @@ public class JPATransaction implements Transaction { | ||
75 | @Override | 87 | @Override |
76 | public void begin() { | 88 | public void begin() { |
77 | EntityTransaction transaction; | 89 | EntityTransaction transaction; |
78 | - for (EntityManager entityManager : getDelegate()) { | ||
79 | - transaction = entityManager.getTransaction(); | ||
80 | - | ||
81 | - if (!transaction.isActive()) { | ||
82 | - transaction.begin(); | 90 | + |
91 | + try { | ||
92 | + for (EntityManager entityManager : getDelegate()) { | ||
93 | + transaction = entityManager.getTransaction(); | ||
94 | + | ||
95 | + if (!transaction.isActive()) { | ||
96 | + transaction.begin(); | ||
97 | + } | ||
83 | } | 98 | } |
84 | } | 99 | } |
100 | + catch(Exception e) { | ||
101 | + /* | ||
102 | + Precisamos marcar para rollback todos os EntityManagers que conseguimos iniciar | ||
103 | + antes da exceção ser disparada. | ||
104 | + */ | ||
105 | + setRollbackOnly(); | ||
106 | + | ||
107 | + throw new TransactionException(e); | ||
108 | + } | ||
85 | } | 109 | } |
86 | 110 | ||
87 | @Override | 111 | @Override |
88 | public void commit() { | 112 | public void commit() { |
89 | EntityTransaction transaction; | 113 | EntityTransaction transaction; |
90 | - for (EntityManager entityManager : getDelegate()) { | ||
91 | - transaction = entityManager.getTransaction(); | ||
92 | - | ||
93 | - if (transaction.isActive()) { | ||
94 | - transaction.commit(); | 114 | + |
115 | + int commitedEntityManagers = 0; | ||
116 | + try { | ||
117 | + for (EntityManager entityManager : getDelegate()) { | ||
118 | + transaction = entityManager.getTransaction(); | ||
119 | + | ||
120 | + if (transaction.isActive()) { | ||
121 | + transaction.commit(); | ||
122 | + commitedEntityManagers++; | ||
123 | + } | ||
124 | + } | ||
125 | + } | ||
126 | + catch(Exception e) { | ||
127 | + /* | ||
128 | + Precisamos marcar para rollback todos os EntityManagers que conseguimos iniciar | ||
129 | + antes da exceção ser disparada. | ||
130 | + */ | ||
131 | + setRollbackOnly(); | ||
132 | + | ||
133 | + /* | ||
134 | + Esse erro pode ser bastante problemático, pois EntityManagers já encerrados com commit | ||
135 | + não podem ser revertidos. Por isso anexamos uma mensagem recomendando ao usuário que considere o uso de JTA em sua aplicação. | ||
136 | + */ | ||
137 | + if (commitedEntityManagers>0) { | ||
138 | + throw new TransactionException(getBundle().getString("partial-rollback-problem"),e); | ||
139 | + } | ||
140 | + else { | ||
141 | + throw new TransactionException(e); | ||
95 | } | 142 | } |
96 | } | 143 | } |
97 | } | 144 | } |
@@ -99,25 +146,37 @@ public class JPATransaction implements Transaction { | @@ -99,25 +146,37 @@ public class JPATransaction implements Transaction { | ||
99 | @Override | 146 | @Override |
100 | public void rollback() { | 147 | public void rollback() { |
101 | EntityTransaction transaction; | 148 | EntityTransaction transaction; |
102 | - for (EntityManager entityManager : getDelegate()) { | ||
103 | - transaction = entityManager.getTransaction(); | ||
104 | - | ||
105 | - if (transaction.isActive()) { | ||
106 | - transaction.rollback(); | 149 | + |
150 | + try { | ||
151 | + for (EntityManager entityManager : getDelegate()) { | ||
152 | + transaction = entityManager.getTransaction(); | ||
153 | + | ||
154 | + if (transaction.isActive()) { | ||
155 | + transaction.rollback(); | ||
156 | + } | ||
107 | } | 157 | } |
108 | } | 158 | } |
159 | + catch(Exception e) { | ||
160 | + throw new TransactionException(e); | ||
161 | + } | ||
109 | } | 162 | } |
110 | 163 | ||
111 | @Override | 164 | @Override |
112 | public void setRollbackOnly() { | 165 | public void setRollbackOnly() { |
113 | EntityTransaction transaction; | 166 | EntityTransaction transaction; |
114 | - for (EntityManager entityManager : getDelegate()) { | ||
115 | - transaction = entityManager.getTransaction(); | ||
116 | - | ||
117 | - if (transaction.isActive()) { | ||
118 | - transaction.setRollbackOnly(); | 167 | + |
168 | + try { | ||
169 | + for (EntityManager entityManager : getDelegate()) { | ||
170 | + transaction = entityManager.getTransaction(); | ||
171 | + | ||
172 | + if (transaction.isActive()) { | ||
173 | + transaction.setRollbackOnly(); | ||
174 | + } | ||
119 | } | 175 | } |
120 | } | 176 | } |
177 | + catch(Exception e) { | ||
178 | + throw new TransactionException(e); | ||
179 | + } | ||
121 | } | 180 | } |
122 | 181 | ||
123 | @Override | 182 | @Override |
@@ -125,14 +184,19 @@ public class JPATransaction implements Transaction { | @@ -125,14 +184,19 @@ public class JPATransaction implements Transaction { | ||
125 | boolean active = false; | 184 | boolean active = false; |
126 | 185 | ||
127 | EntityTransaction transaction; | 186 | EntityTransaction transaction; |
128 | - for (EntityManager entityManager : getDelegate()) { | ||
129 | - transaction = entityManager.getTransaction(); | ||
130 | - | ||
131 | - if (transaction.isActive()) { | ||
132 | - active = true; | ||
133 | - break; | 187 | + try { |
188 | + for (EntityManager entityManager : getDelegate()) { | ||
189 | + transaction = entityManager.getTransaction(); | ||
190 | + | ||
191 | + if (transaction.isActive()) { | ||
192 | + active = true; | ||
193 | + break; | ||
194 | + } | ||
134 | } | 195 | } |
135 | } | 196 | } |
197 | + catch (Exception e) { | ||
198 | + throw new TransactionException(e); | ||
199 | + } | ||
136 | 200 | ||
137 | return active; | 201 | return active; |
138 | } | 202 | } |
@@ -142,14 +206,19 @@ public class JPATransaction implements Transaction { | @@ -142,14 +206,19 @@ public class JPATransaction implements Transaction { | ||
142 | boolean rollbackOnly = false; | 206 | boolean rollbackOnly = false; |
143 | 207 | ||
144 | EntityTransaction transaction; | 208 | EntityTransaction transaction; |
145 | - for (EntityManager entityManager : getDelegate()) { | ||
146 | - transaction = entityManager.getTransaction(); | ||
147 | - | ||
148 | - if (transaction.isActive() && transaction.getRollbackOnly()) { | ||
149 | - rollbackOnly = true; | ||
150 | - break; | 209 | + try { |
210 | + for (EntityManager entityManager : getDelegate()) { | ||
211 | + transaction = entityManager.getTransaction(); | ||
212 | + | ||
213 | + if (transaction.isActive() && transaction.getRollbackOnly()) { | ||
214 | + rollbackOnly = true; | ||
215 | + break; | ||
216 | + } | ||
151 | } | 217 | } |
152 | } | 218 | } |
219 | + catch(Exception e) { | ||
220 | + throw new TransactionException(e); | ||
221 | + } | ||
153 | 222 | ||
154 | return rollbackOnly; | 223 | return rollbackOnly; |
155 | } | 224 | } |
impl/extension/jpa/src/main/resources/demoiselle-jpa-bundle.properties
@@ -47,4 +47,5 @@ malformed-jpql=Consulta JPQL mal formada para pagina\u00E7\u00E3o de dados. | @@ -47,4 +47,5 @@ malformed-jpql=Consulta JPQL mal formada para pagina\u00E7\u00E3o de dados. | ||
47 | invalid-scope-for-entity-manager=O escopo especificado para o Entity Manager \u00E9 inv\u00E1lido. Por favor informe um dos escopos v\u00E1lidos para a propriedade frameworkdemoiselle.persistence.entitymanager.scope\: request, session, view, conversation, application | 47 | invalid-scope-for-entity-manager=O escopo especificado para o Entity Manager \u00E9 inv\u00E1lido. Por favor informe um dos escopos v\u00E1lidos para a propriedade frameworkdemoiselle.persistence.entitymanager.scope\: request, session, view, conversation, application |
48 | entity-manager-scope-not-defined=N\u00E3o foi poss\u00EDvel ler o escopo configurado para o Entity Manager, usando o escopo padr\u00E3o [{0}] | 48 | entity-manager-scope-not-defined=N\u00E3o foi poss\u00EDvel ler o escopo configurado para o Entity Manager, usando o escopo padr\u00E3o [{0}] |
49 | passivable-scope-without-optimistic-lock=Um Entity Manager armazenado no escopo [{0}] suporta apenas trava otimista com vers\u00E3o. Use o tipo adequado ou remova a trava. (veja [LockModeType.OPTIMISTIC_FORCE_INCREMENT]) | 49 | passivable-scope-without-optimistic-lock=Um Entity Manager armazenado no escopo [{0}] suporta apenas trava otimista com vers\u00E3o. Use o tipo adequado ou remova a trava. (veja [LockModeType.OPTIMISTIC_FORCE_INCREMENT]) |
50 | -defining-entity-manager-scope=Definindo escopo [{0}] para produtor de Entity Manager | ||
51 | \ No newline at end of file | 50 | \ No newline at end of file |
51 | +defining-entity-manager-scope=Definindo escopo [{0}] para produtor de Entity Manager | ||
52 | +partial-rollback-problem=N\u00E3o foi poss\u00EDvel reverter a transa\u00E7\u00E3o para todos os EntityManager's configurados, favor considerar o uso de transa\u00E7\u00F5es JTA em uma aplica\u00E7\u00E3o com m\u00FAltiplos EntityManager's |
impl/extension/jpa/src/test/java/transaction/interceptor/JPATransactionTest.java
@@ -8,6 +8,8 @@ import static junit.framework.Assert.assertTrue; | @@ -8,6 +8,8 @@ import static junit.framework.Assert.assertTrue; | ||
8 | import javax.inject.Inject; | 8 | import javax.inject.Inject; |
9 | import javax.persistence.EntityManager; | 9 | import javax.persistence.EntityManager; |
10 | 10 | ||
11 | +import junit.framework.Assert; | ||
12 | + | ||
11 | import org.jboss.arquillian.container.test.api.Deployment; | 13 | import org.jboss.arquillian.container.test.api.Deployment; |
12 | import org.jboss.arquillian.junit.Arquillian; | 14 | import org.jboss.arquillian.junit.Arquillian; |
13 | import org.jboss.shrinkwrap.api.spec.WebArchive; | 15 | import org.jboss.shrinkwrap.api.spec.WebArchive; |
@@ -18,6 +20,7 @@ import org.junit.runner.RunWith; | @@ -18,6 +20,7 @@ import org.junit.runner.RunWith; | ||
18 | import test.Tests; | 20 | import test.Tests; |
19 | import br.gov.frameworkdemoiselle.annotation.Name; | 21 | import br.gov.frameworkdemoiselle.annotation.Name; |
20 | import br.gov.frameworkdemoiselle.transaction.TransactionContext; | 22 | import br.gov.frameworkdemoiselle.transaction.TransactionContext; |
23 | +import br.gov.frameworkdemoiselle.transaction.TransactionException; | ||
21 | 24 | ||
22 | @RunWith(Arquillian.class) | 25 | @RunWith(Arquillian.class) |
23 | public class JPATransactionTest { | 26 | public class JPATransactionTest { |
@@ -74,6 +77,20 @@ public class JPATransactionTest { | @@ -74,6 +77,20 @@ public class JPATransactionTest { | ||
74 | assertEquals("desc-1", entity1.getDescription()); | 77 | assertEquals("desc-1", entity1.getDescription()); |
75 | assertEquals("desc-2", entity2.getDescription()); | 78 | assertEquals("desc-2", entity2.getDescription()); |
76 | } | 79 | } |
80 | + | ||
81 | + @Test | ||
82 | + public void commitWithException() { | ||
83 | + tb.commitWithException(); | ||
84 | + | ||
85 | + try { | ||
86 | + tb.commitWithException(); | ||
87 | + Assert.fail(); | ||
88 | + } | ||
89 | + catch(TransactionException te) { | ||
90 | + te.printStackTrace(); | ||
91 | + //success | ||
92 | + } | ||
93 | + } | ||
77 | 94 | ||
78 | @Test | 95 | @Test |
79 | public void rollbackWithSuccess() { | 96 | public void rollbackWithSuccess() { |
impl/extension/jpa/src/test/java/transaction/interceptor/TransactionalBusiness.java
@@ -42,6 +42,15 @@ public class TransactionalBusiness { | @@ -42,6 +42,15 @@ public class TransactionalBusiness { | ||
42 | em1.persist(entity1); | 42 | em1.persist(entity1); |
43 | em2.persist(entity2); | 43 | em2.persist(entity2); |
44 | } | 44 | } |
45 | + | ||
46 | + @Transactional | ||
47 | + public void commitWithException() { | ||
48 | + MyEntity1 entity1 = new MyEntity1(); | ||
49 | + entity1.setId(createId("id-1")); | ||
50 | + entity1.setDescription("desc-1"); | ||
51 | + | ||
52 | + em1.persist(entity1); | ||
53 | + } | ||
45 | 54 | ||
46 | @Transactional | 55 | @Transactional |
47 | public void rollbackWithSuccess() throws Exception { | 56 | public void rollbackWithSuccess() throws Exception { |
impl/extension/jpa/src/test/java/transaction/manual/JPATransactionTest.java
@@ -10,6 +10,8 @@ import javax.inject.Inject; | @@ -10,6 +10,8 @@ import javax.inject.Inject; | ||
10 | import javax.persistence.EntityManager; | 10 | import javax.persistence.EntityManager; |
11 | import javax.persistence.TransactionRequiredException; | 11 | import javax.persistence.TransactionRequiredException; |
12 | 12 | ||
13 | +import junit.framework.Assert; | ||
14 | + | ||
13 | import org.jboss.arquillian.container.test.api.Deployment; | 15 | import org.jboss.arquillian.container.test.api.Deployment; |
14 | import org.jboss.arquillian.junit.Arquillian; | 16 | import org.jboss.arquillian.junit.Arquillian; |
15 | import org.jboss.shrinkwrap.api.spec.WebArchive; | 17 | import org.jboss.shrinkwrap.api.spec.WebArchive; |
@@ -21,6 +23,7 @@ import br.gov.frameworkdemoiselle.annotation.Name; | @@ -21,6 +23,7 @@ import br.gov.frameworkdemoiselle.annotation.Name; | ||
21 | import br.gov.frameworkdemoiselle.transaction.JPATransaction; | 23 | import br.gov.frameworkdemoiselle.transaction.JPATransaction; |
22 | import br.gov.frameworkdemoiselle.transaction.Transaction; | 24 | import br.gov.frameworkdemoiselle.transaction.Transaction; |
23 | import br.gov.frameworkdemoiselle.transaction.TransactionContext; | 25 | import br.gov.frameworkdemoiselle.transaction.TransactionContext; |
26 | +import br.gov.frameworkdemoiselle.transaction.TransactionException; | ||
24 | import br.gov.frameworkdemoiselle.util.Beans; | 27 | import br.gov.frameworkdemoiselle.util.Beans; |
25 | import br.gov.frameworkdemoiselle.util.NameQualifier; | 28 | import br.gov.frameworkdemoiselle.util.NameQualifier; |
26 | 29 | ||
@@ -81,6 +84,42 @@ public class JPATransactionTest { | @@ -81,6 +84,42 @@ public class JPATransactionTest { | ||
81 | assertEquals("desc-1", persisted1.getDescription()); | 84 | assertEquals("desc-1", persisted1.getDescription()); |
82 | assertEquals("desc-2", persisted2.getDescription()); | 85 | assertEquals("desc-2", persisted2.getDescription()); |
83 | } | 86 | } |
87 | + | ||
88 | + @Test | ||
89 | + public void commitWithException() { | ||
90 | + Transaction transaction = transactionContext.getCurrentTransaction(); | ||
91 | + | ||
92 | + MyEntity1 entity1 = new MyEntity1(); | ||
93 | + entity1.setId(createId("id-7")); | ||
94 | + entity1.setDescription("desc-7"); | ||
95 | + | ||
96 | + assertFalse(transaction.isActive()); | ||
97 | + transaction.begin(); | ||
98 | + assertTrue(transaction.isActive()); | ||
99 | + | ||
100 | + em1.persist(entity1); | ||
101 | + transaction.commit(); | ||
102 | + em1.clear(); | ||
103 | + | ||
104 | + entity1 = new MyEntity1(); | ||
105 | + entity1.setId(createId("id-7")); | ||
106 | + entity1.setDescription("desc-7"); | ||
107 | + | ||
108 | + assertFalse(transaction.isActive()); | ||
109 | + transaction.begin(); | ||
110 | + assertTrue(transaction.isActive()); | ||
111 | + | ||
112 | + em1.persist(entity1); | ||
113 | + | ||
114 | + try { | ||
115 | + transaction.commit(); | ||
116 | + Assert.fail(); | ||
117 | + } | ||
118 | + catch(TransactionException te) { | ||
119 | + te.printStackTrace(); | ||
120 | + //success | ||
121 | + } | ||
122 | + } | ||
84 | 123 | ||
85 | @Test(expected = TransactionRequiredException.class) | 124 | @Test(expected = TransactionRequiredException.class) |
86 | public void checkNoTransactionAutomaticallyLoaded() { | 125 | public void checkNoTransactionAutomaticallyLoaded() { |
impl/extension/jta/src/main/java/br/gov/frameworkdemoiselle/transaction/JTATransaction.java
@@ -77,7 +77,7 @@ public class JTATransaction implements Transaction { | @@ -77,7 +77,7 @@ public class JTATransaction implements Transaction { | ||
77 | return getDelegate().getStatus() != STATUS_NO_TRANSACTION; | 77 | return getDelegate().getStatus() != STATUS_NO_TRANSACTION; |
78 | 78 | ||
79 | } catch (SystemException cause) { | 79 | } catch (SystemException cause) { |
80 | - throw new DemoiselleException(cause); | 80 | + throw new TransactionException(cause); |
81 | } | 81 | } |
82 | } | 82 | } |
83 | 83 | ||
@@ -91,7 +91,7 @@ public class JTATransaction implements Transaction { | @@ -91,7 +91,7 @@ public class JTATransaction implements Transaction { | ||
91 | || getDelegate().getStatus() == STATUS_ROLLEDBACK; | 91 | || getDelegate().getStatus() == STATUS_ROLLEDBACK; |
92 | 92 | ||
93 | } catch (SystemException cause) { | 93 | } catch (SystemException cause) { |
94 | - throw new DemoiselleException(cause); | 94 | + throw new TransactionException(cause); |
95 | } | 95 | } |
96 | } | 96 | } |
97 | 97 | ||
@@ -104,7 +104,7 @@ public class JTATransaction implements Transaction { | @@ -104,7 +104,7 @@ public class JTATransaction implements Transaction { | ||
104 | getDelegate().begin(); | 104 | getDelegate().begin(); |
105 | 105 | ||
106 | } catch (Exception cause) { | 106 | } catch (Exception cause) { |
107 | - throw new DemoiselleException(cause); | 107 | + throw new TransactionException(cause); |
108 | } | 108 | } |
109 | } | 109 | } |
110 | 110 | ||
@@ -117,7 +117,7 @@ public class JTATransaction implements Transaction { | @@ -117,7 +117,7 @@ public class JTATransaction implements Transaction { | ||
117 | getDelegate().commit(); | 117 | getDelegate().commit(); |
118 | 118 | ||
119 | } catch (Exception cause) { | 119 | } catch (Exception cause) { |
120 | - throw new DemoiselleException(cause); | 120 | + throw new TransactionException(cause); |
121 | } | 121 | } |
122 | } | 122 | } |
123 | 123 | ||
@@ -130,7 +130,7 @@ public class JTATransaction implements Transaction { | @@ -130,7 +130,7 @@ public class JTATransaction implements Transaction { | ||
130 | getDelegate().rollback(); | 130 | getDelegate().rollback(); |
131 | 131 | ||
132 | } catch (SystemException cause) { | 132 | } catch (SystemException cause) { |
133 | - throw new DemoiselleException(cause); | 133 | + throw new TransactionException(cause); |
134 | } | 134 | } |
135 | } | 135 | } |
136 | 136 | ||
@@ -143,7 +143,7 @@ public class JTATransaction implements Transaction { | @@ -143,7 +143,7 @@ public class JTATransaction implements Transaction { | ||
143 | getDelegate().setRollbackOnly(); | 143 | getDelegate().setRollbackOnly(); |
144 | 144 | ||
145 | } catch (SystemException cause) { | 145 | } catch (SystemException cause) { |
146 | - throw new DemoiselleException(cause); | 146 | + throw new TransactionException(cause); |
147 | } | 147 | } |
148 | } | 148 | } |
149 | } | 149 | } |
impl/extension/jta/src/test/java/jtatransaction/interceptor/InterceptorJTATransactionTest.java
@@ -8,6 +8,8 @@ import javax.persistence.EntityManager; | @@ -8,6 +8,8 @@ import javax.persistence.EntityManager; | ||
8 | import javax.persistence.PersistenceContext; | 8 | import javax.persistence.PersistenceContext; |
9 | import javax.persistence.TransactionRequiredException; | 9 | import javax.persistence.TransactionRequiredException; |
10 | 10 | ||
11 | +import junit.framework.Assert; | ||
12 | + | ||
11 | import org.jboss.arquillian.container.test.api.Deployment; | 13 | import org.jboss.arquillian.container.test.api.Deployment; |
12 | import org.jboss.arquillian.junit.Arquillian; | 14 | import org.jboss.arquillian.junit.Arquillian; |
13 | import org.jboss.shrinkwrap.api.spec.WebArchive; | 15 | import org.jboss.shrinkwrap.api.spec.WebArchive; |
@@ -19,6 +21,7 @@ import test.Tests; | @@ -19,6 +21,7 @@ import test.Tests; | ||
19 | import br.gov.frameworkdemoiselle.DemoiselleException; | 21 | import br.gov.frameworkdemoiselle.DemoiselleException; |
20 | import br.gov.frameworkdemoiselle.transaction.JTATransaction; | 22 | import br.gov.frameworkdemoiselle.transaction.JTATransaction; |
21 | import br.gov.frameworkdemoiselle.transaction.TransactionContext; | 23 | import br.gov.frameworkdemoiselle.transaction.TransactionContext; |
24 | +import br.gov.frameworkdemoiselle.transaction.TransactionException; | ||
22 | import br.gov.frameworkdemoiselle.util.Beans; | 25 | import br.gov.frameworkdemoiselle.util.Beans; |
23 | 26 | ||
24 | @RunWith(Arquillian.class) | 27 | @RunWith(Arquillian.class) |
@@ -79,6 +82,23 @@ public class InterceptorJTATransactionTest { | @@ -79,6 +82,23 @@ public class InterceptorJTATransactionTest { | ||
79 | assertFalse(transactionContext.getCurrentTransaction().isActive()); | 82 | assertFalse(transactionContext.getCurrentTransaction().isActive()); |
80 | 83 | ||
81 | } | 84 | } |
85 | + | ||
86 | + @Test | ||
87 | + public void commitWithException() { | ||
88 | + | ||
89 | + TransactionalBusiness business = Beans.getReference(TransactionalBusiness.class); | ||
90 | + | ||
91 | + business.commitWithException(); | ||
92 | + | ||
93 | + try { | ||
94 | + business.commitWithException(); | ||
95 | + Assert.fail(); | ||
96 | + } | ||
97 | + catch(TransactionException te) { | ||
98 | + te.printStackTrace(); | ||
99 | + //sucess | ||
100 | + } | ||
101 | + } | ||
82 | 102 | ||
83 | @Test(expected = TransactionRequiredException.class) | 103 | @Test(expected = TransactionRequiredException.class) |
84 | public void checkNoTransactionAutomaticallyLoaded() { | 104 | public void checkNoTransactionAutomaticallyLoaded() { |
impl/extension/jta/src/test/java/jtatransaction/interceptor/TransactionalBusiness.java
@@ -35,6 +35,16 @@ public class TransactionalBusiness { | @@ -35,6 +35,16 @@ public class TransactionalBusiness { | ||
35 | em1.flush(); | 35 | em1.flush(); |
36 | em2.flush(); | 36 | em2.flush(); |
37 | } | 37 | } |
38 | + | ||
39 | + @Transactional | ||
40 | + public void commitWithException() { | ||
41 | + MyEntity1 entity1 = new MyEntity1(); | ||
42 | + entity1.setId(createId("id-1")); | ||
43 | + entity1.setDescription("desc-1"); | ||
44 | + | ||
45 | + em1.joinTransaction(); | ||
46 | + em1.persist(entity1); | ||
47 | + } | ||
38 | 48 | ||
39 | public void checkNoTransactionAutomaticallyLoaded() { | 49 | public void checkNoTransactionAutomaticallyLoaded() { |
40 | MyEntity1 entity = new MyEntity1(); | 50 | MyEntity1 entity = new MyEntity1(); |
impl/extension/jta/src/test/java/jtatransaction/manual/ManualJTATransactionTest.java
@@ -9,6 +9,8 @@ import javax.persistence.EntityManager; | @@ -9,6 +9,8 @@ import javax.persistence.EntityManager; | ||
9 | import javax.persistence.PersistenceContext; | 9 | import javax.persistence.PersistenceContext; |
10 | import javax.persistence.TransactionRequiredException; | 10 | import javax.persistence.TransactionRequiredException; |
11 | 11 | ||
12 | +import junit.framework.Assert; | ||
13 | + | ||
12 | import org.jboss.arquillian.container.test.api.Deployment; | 14 | import org.jboss.arquillian.container.test.api.Deployment; |
13 | import org.jboss.arquillian.junit.Arquillian; | 15 | import org.jboss.arquillian.junit.Arquillian; |
14 | import org.jboss.shrinkwrap.api.spec.WebArchive; | 16 | import org.jboss.shrinkwrap.api.spec.WebArchive; |
@@ -20,6 +22,7 @@ import test.Tests; | @@ -20,6 +22,7 @@ import test.Tests; | ||
20 | import br.gov.frameworkdemoiselle.transaction.JTATransaction; | 22 | import br.gov.frameworkdemoiselle.transaction.JTATransaction; |
21 | import br.gov.frameworkdemoiselle.transaction.Transaction; | 23 | import br.gov.frameworkdemoiselle.transaction.Transaction; |
22 | import br.gov.frameworkdemoiselle.transaction.TransactionContext; | 24 | import br.gov.frameworkdemoiselle.transaction.TransactionContext; |
25 | +import br.gov.frameworkdemoiselle.transaction.TransactionException; | ||
23 | import br.gov.frameworkdemoiselle.util.Beans; | 26 | import br.gov.frameworkdemoiselle.util.Beans; |
24 | 27 | ||
25 | @RunWith(Arquillian.class) | 28 | @RunWith(Arquillian.class) |
@@ -97,6 +100,47 @@ public class ManualJTATransactionTest { | @@ -97,6 +100,47 @@ public class ManualJTATransactionTest { | ||
97 | assertEquals("desc-1", persisted1.getDescription()); | 100 | assertEquals("desc-1", persisted1.getDescription()); |
98 | assertEquals("desc-2", persisted2.getDescription()); | 101 | assertEquals("desc-2", persisted2.getDescription()); |
99 | } | 102 | } |
103 | + | ||
104 | + @Test | ||
105 | + public void commitWithException() { | ||
106 | + Transaction transaction = transactionContext.getCurrentTransaction(); | ||
107 | + | ||
108 | + MyEntity1 entity1 = new MyEntity1(); | ||
109 | + entity1.setId(createId("id-1")); | ||
110 | + entity1.setDescription("desc-1"); | ||
111 | + | ||
112 | + assertFalse(transaction.isActive()); | ||
113 | + | ||
114 | + transaction.begin(); | ||
115 | + assertTrue(transaction.isActive()); | ||
116 | + | ||
117 | + em1.joinTransaction(); | ||
118 | + | ||
119 | + em1.persist(entity1); | ||
120 | + | ||
121 | + transaction.commit(); | ||
122 | + em1.clear(); | ||
123 | + | ||
124 | + entity1 = new MyEntity1(); | ||
125 | + entity1.setId(createId("id-1")); | ||
126 | + entity1.setDescription("desc-1"); | ||
127 | + | ||
128 | + assertFalse(transaction.isActive()); | ||
129 | + transaction.begin(); | ||
130 | + assertTrue(transaction.isActive()); | ||
131 | + | ||
132 | + em1.joinTransaction(); | ||
133 | + em1.persist(entity1); | ||
134 | + | ||
135 | + try { | ||
136 | + transaction.commit(); | ||
137 | + Assert.fail(); | ||
138 | + } | ||
139 | + catch(TransactionException e) { | ||
140 | + e.printStackTrace(); | ||
141 | + //success | ||
142 | + } | ||
143 | + } | ||
100 | 144 | ||
101 | @Test(expected = TransactionRequiredException.class) | 145 | @Test(expected = TransactionRequiredException.class) |
102 | public void checkNoTransactionAutomaticallyLoaded() { | 146 | public void checkNoTransactionAutomaticallyLoaded() { |