View Javadoc
1   package org.apache.onami.persist;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import javax.inject.Inject;
23  import javax.inject.Singleton;
24  import javax.persistence.EntityManager;
25  
26  import static org.apache.onami.persist.Preconditions.checkNotNull;
27  
28  /**
29   * Factory for transaction facades in case of JTA transactions.
30   */
31  @Singleton
32  class JtaTransactionFacadeFactory
33      implements TransactionFacadeFactory
34  {
35  
36      /**
37       * The facade to the user transaction.
38       */
39      private final UserTransactionFacade utFacade;
40  
41      /**
42       * Provider for the entity manager.
43       * The entity manager will be joined to the the transaction.
44       */
45      private final EntityManagerProvider emProvider;
46  
47      /**
48       * Constructor.
49       *
50       * @param utFacade   the user transaction facade.
51       * @param emProvider the entity manager provider.
52       */
53      @Inject
54      public JtaTransactionFacadeFactory( UserTransactionFacade utFacade, EntityManagerProvider emProvider )
55      {
56          this.utFacade = checkNotNull( utFacade, "utFacade is mandatory!" );
57          this.emProvider = checkNotNull( emProvider, "emProvider is mandatory!" );
58      }
59  
60      /**
61       * {@inheritDoc}
62       */
63      // @Override
64      public TransactionFacade createTransactionFacade()
65      {
66          if ( utFacade.isActive() )
67          {
68              return new Inner( utFacade, emProvider.get() );
69          }
70          else
71          {
72              return new Outer( utFacade, emProvider.get() );
73          }
74      }
75  
76      /**
77       * TransactionFacade representing an inner (nested) transaction. Starting and
78       * committing a transaction has no effect. This Facade will set the
79       * rollbackOnly flag on the underlying transaction in case of a rollback.
80       */
81      private static class Inner
82          implements TransactionFacade
83      {
84          private final UserTransactionFacade txn;
85  
86          private final EntityManager em;
87  
88          Inner( UserTransactionFacade txn, EntityManager em )
89          {
90              this.txn = checkNotNull( txn, "txn is mandatory!" );
91              this.em = checkNotNull( em, "em is mandatory!" );
92          }
93  
94          /**
95           * {@inheritDoc}
96           */
97          // @Override
98          public void begin()
99          {
100             em.joinTransaction();
101         }
102 
103         /**
104          * {@inheritDoc}
105          */
106         // @Override
107         public void commit()
108         {
109             // Do nothing
110         }
111 
112         /**
113          * {@inheritDoc}
114          */
115         // @Override
116         public void rollback()
117         {
118             txn.setRollbackOnly();
119         }
120     }
121 
122     /**
123      * TransactionFacade representing an outer transaction. This Facade starts
124      * and ends the transaction. If an inner transaction has set the rollbackOnly
125      * flag the transaction will be rolled back in any case.
126      */
127     private static class Outer
128         implements TransactionFacade
129     {
130         private final UserTransactionFacade txn;
131 
132         private final EntityManager em;
133 
134         Outer( UserTransactionFacade txn, EntityManager em )
135         {
136             this.txn = checkNotNull( txn, "txn is mandatory!" );
137             this.em = checkNotNull( em, "em is mandatory!" );
138         }
139 
140         /**
141          * {@inheritDoc}
142          */
143         // @Override
144         public void begin()
145         {
146             txn.begin();
147             em.joinTransaction();
148         }
149 
150         /**
151          * {@inheritDoc}
152          */
153         // @Override
154         public void commit()
155         {
156             if ( txn.getRollbackOnly() )
157             {
158                 txn.rollback();
159             }
160             else
161             {
162                 txn.commit();
163             }
164         }
165 
166         /**
167          * {@inheritDoc}
168          */
169         // @Override
170         public void rollback()
171         {
172             txn.rollback();
173         }
174     }
175 
176 }