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.EntityTransaction;
25  
26  import static org.apache.onami.persist.Preconditions.checkNotNull;
27  
28  /**
29   * Factory for transaction facades in case of resource local transactions.
30   */
31  @Singleton
32  class ResourceLocalTransactionFacadeFactory
33      implements TransactionFacadeFactory
34  {
35  
36      /**
37       * The provider for the entity manager.
38       */
39      private final EntityManagerProvider emProvider;
40  
41      /**
42       * Constructor.
43       *
44       * @param emProvider the provider for the entity manager
45       */
46      @Inject
47      ResourceLocalTransactionFacadeFactory( EntityManagerProvider emProvider )
48      {
49          this.emProvider = checkNotNull( emProvider, "emProvider is mandatory!" );
50      }
51  
52      /**
53       * {@inheritDoc}
54       */
55      // @Override
56      public TransactionFacade createTransactionFacade()
57      {
58          final EntityTransaction txn = emProvider.get().getTransaction();
59          if ( txn.isActive() )
60          {
61              return new Inner( txn );
62          }
63          else
64          {
65              return new Outer( txn );
66          }
67      }
68  
69      /**
70       * TransactionFacade representing an inner (nested) transaction.
71       * Starting and committing a transaction has no effect.
72       * This facade will set the rollbackOnly flag in case of a roll back.
73       */
74      private static class Inner
75          implements TransactionFacade
76      {
77          private final EntityTransaction txn;
78  
79          Inner( EntityTransaction txn )
80          {
81              this.txn = checkNotNull( txn, "txn is mandatory!" );
82          }
83  
84          /**
85           * {@inheritDoc}
86           */
87          // @Override
88          public void begin()
89          {
90              // Do nothing
91          }
92  
93          /**
94           * {@inheritDoc}
95           */
96          // @Override
97          public void commit()
98          {
99              // Do nothing
100         }
101 
102         /**
103          * {@inheritDoc}
104          */
105         // @Override
106         public void rollback()
107         {
108             txn.setRollbackOnly();
109         }
110     }
111 
112     /**
113      * TransactionFacade representing an outer transaction.
114      * This facade starts and ends the transaction.
115      * If an inner transaction has set the rollbackOnly flag the transaction will be rolled back in any case.
116      */
117     private static class Outer
118         implements TransactionFacade
119     {
120         private final EntityTransaction txn;
121 
122         /**
123          * {@inheritDoc}
124          */
125         Outer( EntityTransaction txn )
126         {
127             this.txn = checkNotNull( txn, "txn is mandatory!" );
128         }
129 
130         /**
131          * {@inheritDoc}
132          */
133         // @Override
134         public void begin()
135         {
136             txn.begin();
137         }
138 
139         /**
140          * {@inheritDoc}
141          */
142         // @Override
143         public void commit()
144         {
145             if ( txn.getRollbackOnly() )
146             {
147                 txn.rollback();
148             }
149             else
150             {
151                 txn.commit();
152             }
153         }
154 
155         /**
156          * {@inheritDoc}
157          */
158         // @Override
159         public void rollback()
160         {
161             txn.rollback();
162         }
163     }
164 
165 }