Commit 7fb2f7419903f224fe834664005827b4db4ecd28

Authored by Emerson Oliveira
2 parents 52cf553d 11cbecea
Exists in master

Merge branch 'master' of git@github.com:demoiselle/framework.git

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() {