View Javadoc
1   /*
2    * Copyright (c) 2002-2014, Mairie de Paris
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions
7    * are met:
8    *
9    *  1. Redistributions of source code must retain the above copyright notice
10   *     and the following disclaimer.
11   *
12   *  2. Redistributions in binary form must reproduce the above copyright notice
13   *     and the following disclaimer in the documentation and/or other materials
14   *     provided with the distribution.
15   *
16   *  3. Neither the name of 'Mairie de Paris' nor 'Lutece' nor the names of its
17   *     contributors may be used to endorse or promote products derived from
18   *     this software without specific prior written permission.
19   *
20   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
24   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30   * POSSIBILITY OF SUCH DAMAGE.
31   *
32   * License 1.0
33   */
34  package fr.paris.lutece.util.jpa.transaction;
35  
36  import fr.paris.lutece.util.jpa.JPAConstants;
37  
38  import org.apache.log4j.Logger;
39  
40  import org.springframework.transaction.PlatformTransactionManager;
41  import org.springframework.transaction.TransactionDefinition;
42  import org.springframework.transaction.TransactionException;
43  import org.springframework.transaction.TransactionStatus;
44  import org.springframework.transaction.support.TransactionSynchronizationManager;
45  
46  import java.util.Collections;
47  import java.util.List;
48  
49  
50  /**
51   *
52   * Manages multi transaction
53   * @see {@link http://www.javaworld.com/javaworld/jw-01-2009/jw-01-spring-transactions.html?page=6}
54   *
55   */
56  public class ChainedTransactionManager implements PlatformTransactionManager
57  {
58      private static final Logger _log = Logger.getLogger( JPAConstants.JPA_LOGGER );
59      private List<PlatformTransactionManager> _transactionManagers;
60  
61      /**
62       * Builds a new ChainedTransactionManager
63       */
64      public ChainedTransactionManager(  )
65      {
66      }
67  
68      /**
69       * Begin a transaction for all transaction managers {@inheritDoc}
70       */
71      public TransactionStatus getTransaction( TransactionDefinition definition )
72          throws TransactionException
73      {
74          if ( _transactionManagers.isEmpty(  ) )
75          {
76              return null;
77          }
78  
79          MultiTransactionStatus mts = new MultiTransactionStatus( _transactionManagers.get( 0 ) );
80  
81          if ( !TransactionSynchronizationManager.isSynchronizationActive(  ) )
82          {
83              TransactionSynchronizationManager.initSynchronization(  );
84              mts.setNewSynchonization(  );
85  
86              if ( _log.isDebugEnabled(  ) )
87              {
88                  _log.debug( "Begin transaction : " + mts.toString(  ) );
89              }
90          }
91  
92          for ( PlatformTransactionManager transactionManager : _transactionManagers )
93          {
94              mts.getTransactionStatuses(  ).put( transactionManager, transactionManager.getTransaction( definition ) );
95          }
96  
97          return mts;
98      }
99  
100     /**
101      *
102      * {@inheritDoc}
103      */
104     public void commit( TransactionStatus status ) throws TransactionException
105     {
106         for ( PlatformTransactionManager transactionManager : _transactionManagers )
107         {
108             TransactionStatus transactionStatus = null;
109 
110             try
111             {
112                 transactionStatus = ( (MultiTransactionStatus) status ).getTransactionStatus( transactionManager );
113                 transactionManager.commit( transactionStatus );
114             }
115             catch ( Exception e )
116             {
117                 _log.error( e.getMessage(  ), e );
118 
119                 // transactionManager.rollback( transactionStatus );
120             }
121         }
122 
123         if ( _log.isDebugEnabled(  ) )
124         {
125             _log.debug( "Ending transaction : " + status.toString(  ) );
126         }
127 
128         if ( ( (MultiTransactionStatus) status ).isNewSynchonization(  ) )
129         {
130             TransactionSynchronizationManager.clear(  );
131         }
132     }
133 
134     /**
135      *
136      * {@inheritDoc}
137      */
138     public void rollback( TransactionStatus status ) throws TransactionException
139     {
140         for ( PlatformTransactionManager dataSourceManager : _transactionManagers )
141         {
142             try
143             {
144                 dataSourceManager.rollback( ( ( (MultiTransactionStatus) status ).getTransactionStatus( 
145                         dataSourceManager ) ) );
146             }
147             catch ( Exception ex )
148             {
149                 _log.error( ex.getMessage(  ), ex );
150             }
151         }
152 
153         if ( ( (MultiTransactionStatus) status ).isNewSynchonization(  ) )
154         {
155             TransactionSynchronizationManager.clear(  );
156         }
157     }
158 
159     /**
160      * "Getter method" pour la variable {@link #_transactionManagers}
161      * @return La variable {@link #_transactionManagers}
162      */
163     public List<PlatformTransactionManager> getTransactionManagers(  )
164     {
165         return _transactionManagers;
166     }
167 
168     /**
169      * "Setter method" pour la variable {@link #_transactionManagers}
170      * @param managers La nouvelle valeur de la variable {@link #_transactionManagers}
171      */
172     public void setTransactionManagers( List<PlatformTransactionManager> managers )
173     {
174         if ( ( managers == null ) || managers.isEmpty(  ) )
175         {
176             _transactionManagers = Collections.emptyList(  );
177         }
178         else
179         {
180             _transactionManagers = managers;
181 
182             if ( _log.isDebugEnabled(  ) )
183             {
184                 _log.debug( "Transaction Managers : " + _transactionManagers.toString(  ) );
185             }
186         }
187     }
188 }