KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > oracle > toplink > essentials > internal > ejb > cmp3 > transaction > base > EntityTransactionImpl


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the "License"). You may not use this file except
5  * in compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * glassfish/bootstrap/legal/CDDLv1.0.txt or
9  * https://glassfish.dev.java.net/public/CDDLv1.0.html.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * HEADER in each file and include the License file at
15  * glassfish/bootstrap/legal/CDDLv1.0.txt. If applicable,
16  * add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your
18  * own identifying information: Portions Copyright [yyyy]
19  * [name of copyright owner]
20  */

21 // Copyright (c) 1998, 2006, Oracle. All rights reserved.
22
package oracle.toplink.essentials.internal.ejb.cmp3.transaction.base;
23
24 import javax.persistence.RollbackException;
25
26 import oracle.toplink.essentials.exceptions.TransactionException;
27 import oracle.toplink.essentials.internal.ejb.cmp3.base.RepeatableWriteUnitOfWork;
28 import oracle.toplink.essentials.internal.localization.ExceptionLocalization;
29
30 /**
31  * INTERNAL:
32  * Base EntityTransactionImpl
33  * This is a thin wrapper around a UnitOfWork that implements functionality required
34  * by the EntityTransaction interface. The actual interface is implemented by two subclasses:
35  *
36  * @see oracle.toplink.essentials.internal.ejb.cmp3.transaction.EntityTransactionImpl
37  * @see oracle.toplink.essentials.internal.ejb.cmp3.transaction.jdk14.EntityTransactionImpl
38  *
39  * The EntityTransaction is a thin wrapper around a UnitOFWork.
40  */

41 public class EntityTransactionImpl {
42
43         protected EntityTransactionWrapper wrapper;
44         
45         protected boolean active = false;
46         
47         protected Boolean JavaDoc hasLastTransactionCompleted;
48         
49         protected boolean rollbackOnly = false;
50
51         public EntityTransactionImpl(EntityTransactionWrapper wrapper) {
52             this.wrapper = wrapper;
53         }
54       /**
55        * Start the current transaction. This can only be invoked if {@link #isActive()} returns
56        * <code>false</code>.
57        * @throws IllegalStateException if isActive() is true.
58        */

59       public void begin(){
60         if (isActive()){
61           throw new IllegalStateException JavaDoc(TransactionException.transactionIsActive().getMessage());
62         }
63         if (this.wrapper.getEntityManager().isExtended()){
64             // so we have a resource local extended em so get the PC from the entity manager
65
this.wrapper.localUOW = this.wrapper.getEntityManager().getActivePersistenceContext(null);
66             this.wrapper.localUOW.setShouldTerminateTransaction(false);
67         }else{
68             this.wrapper.localUOW = new RepeatableWriteUnitOfWork(this.wrapper.getEntityManager().getServerSession().acquireClientSession());
69             this.wrapper.localUOW.setShouldTerminateTransaction(false);
70             this.wrapper.localUOW.setShouldCascadeCloneToJoinedRelationship(true);
71         }
72         this.active = true;
73       }
74  
75       /**
76        * Commit the current transaction, writing any un-flushed changes to the database.
77        * This can only be invoked if {@link #isActive()} returns <code>true</code>.
78        * @throws IllegalStateException if isActive() is false.
79        */

80       public void commit(){
81         if (!isActive()){
82           throw new IllegalStateException JavaDoc(TransactionException.transactionNotActive().getMessage());
83         }
84         try {
85             transactionCompleted();
86             if (this.wrapper.localUOW != null){
87                 this.wrapper.localUOW.setShouldTerminateTransaction(true);
88                 if (! this.rollbackOnly){
89                     if (this.wrapper.localUOW.shouldResumeUnitOfWorkOnTransactionCompletion()){
90                         this.wrapper.localUOW.commitAndResume();
91                         return;
92                     }else{
93                       this.wrapper.localUOW.commit();
94                     }
95                 }
96                 wrapper.getLocalUnitOfWork().release();
97                 wrapper.getLocalUnitOfWork().getParent().release();
98                 if (this.rollbackOnly){
99                     wrapper.getEntityManager().clear();
100                     throw new RollbackException(ExceptionLocalization.buildMessage("rollback_because_of_rollback_only"));
101                 }
102             }
103         }catch (RuntimeException JavaDoc ex){
104             if (this.wrapper.localUOW != null){
105                 wrapper.getEntityManager().clear();
106                 this.wrapper.localUOW.release();
107                 this.wrapper.localUOW.getParent().release();
108             }
109             throw new RollbackException(ex);
110         } finally {
111             this.active = false;
112             this.rollbackOnly = false;
113             wrapper.setLocalUnitOfWork(null);
114         }
115       }
116  
117       /**
118        * Roll back the current transaction, discarding any changes that have happened
119        * in this transaction. This can only be invoked if {@link #isActive()} returns
120        * <code>true</code>.
121        * @throws IllegalStateException if isActive() is false.
122        */

123       public void rollback(){
124         if (!isActive()){
125           throw new IllegalStateException JavaDoc(TransactionException.transactionNotActive().getMessage());
126         }
127         try{
128             transactionCompleted();
129             if (wrapper.getLocalUnitOfWork() != null){
130                 this.wrapper.localUOW.setShouldTerminateTransaction(true);
131                 this.wrapper.localUOW.release();
132                 this.wrapper.localUOW.getParent().release();
133             }
134         }finally{
135             this.active = false;
136             this.rollbackOnly = false;
137             wrapper.getEntityManager().clear();
138             wrapper.setLocalUnitOfWork(null);
139         }
140       }
141  
142     /**
143     * Mark the current transaction so that the only possible
144     * outcome of the transaction is for the transaction to be
145     * rolled back.
146     * @throws IllegalStateException if isActive() is false.
147     */

148     public void setRollbackOnly(){
149         if (!isActive()){
150             throw new IllegalStateException JavaDoc(TransactionException.transactionNotActive().getMessage());
151         }
152         this.rollbackOnly = true;
153     }
154     
155     /**
156      * Here incase a user does not commit or rollback an enityTransaction but just
157      * throws it away. If we do not rollback the txn the connection will go
158      * back into the pool.
159      */

160     protected void finalize() throws Throwable JavaDoc{
161         try{
162             if (isActive())
163                 this.rollback();
164         }finally{
165             super.finalize();
166         }
167     }
168     /**
169     * Determine whether the current transaction has been marked
170     * for rollback.
171     * @throws IllegalStateException if isActive() is false.
172     */

173     public boolean getRollbackOnly(){
174         if (!isActive()){
175             throw new IllegalStateException JavaDoc(TransactionException.transactionNotActive().getMessage());
176         }
177         return this.rollbackOnly;
178     }
179     
180     /**
181        * Check to see if the current transaction is in progress.
182        */

183       public boolean isActive(){
184           return this.active;
185       }
186
187       /**
188        * These two method used for closing of EntityManager in case there is a transaction in progress:
189        * The first method is called by EntityManager.close method to mark the current transaction,
190        * the second one is called by EntityManager.verifyOpen method.
191        */

192       public void markLastTransaction() {
193           if(hasLastTransactionCompleted == null) {
194               hasLastTransactionCompleted = Boolean.FALSE;
195           }
196       }
197       public boolean hasLastTransactionCompleted() {
198           return hasLastTransactionCompleted != null && hasLastTransactionCompleted.booleanValue();
199       }
200       protected void transactionCompleted() {
201           if(hasLastTransactionCompleted != null) {
202               hasLastTransactionCompleted = Boolean.TRUE;
203           }
204       }
205       
206 }
207
Popular Tags