View Javadoc

1   /**
2    *
3    *  Licensed to the Apache Software Foundation (ASF) under one or more
4    *  contributor license agreements.  See the NOTICE file distributed with
5    *  this work for additional information regarding copyright ownership.
6    *  The ASF licenses this file to You under the Apache License, Version 2.0
7    *  (the "License"); you may not use this file except in compliance with
8    *  the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   *  Unless required by applicable law or agreed to in writing, software
13   *  distributed under the License is distributed on an "AS IS" BASIS,
14   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   *  See the License for the specific language governing permissions and
16   *  limitations under the License.
17   */
18  
19  package org.apache.geronimo.timer;
20  
21  import javax.transaction.TransactionManager;
22  import javax.transaction.Status;
23  
24  import org.apache.commons.logging.Log;
25  import org.apache.commons.logging.LogFactory;
26  
27  /**
28   * @version $Rev: 470597 $ $Date: 2006-11-02 15:30:55 -0800 (Thu, 02 Nov 2006) $
29   */
30  public class TransactionalExecutorTask implements ExecutorTask {
31      private static final Log log = LogFactory.getLog(TransactionalExecutorTask.class);
32  
33      private final Runnable userTask;
34      private final WorkInfo workInfo;
35      private final ThreadPooledTimer threadPooledTimer;
36  
37      private final TransactionManager transactionManager;
38      private final int repeatCount;
39  
40      public TransactionalExecutorTask(Runnable userTask, WorkInfo workInfo, ThreadPooledTimer threadPooledTimer, TransactionManager transactionManager, int repeatCount) {
41          this.userTask = userTask;
42          this.workInfo = workInfo;
43          this.threadPooledTimer = threadPooledTimer;
44          this.transactionManager = transactionManager;
45          this.repeatCount = repeatCount;
46      }
47  
48      public void run() {
49          try {
50              // try to do the work until it succeeded or we reach the repeat count
51              boolean succeeded = false;
52              for (int tries = 0; !succeeded && tries < repeatCount; tries++) {
53                  try {
54                      if (!beginWork()) {
55                          break;
56                      }
57  
58                      work();
59                  } finally {
60                      succeeded = completeWork();
61                  }
62              }
63  
64              // if this was a one time thing, remove the job
65              if (workInfo.isOneTime()) {
66                  threadPooledTimer.removeWorkInfo(workInfo);
67              }
68  
69              // if we didn't succeed, log it
70              if (!succeeded) {
71                  log.warn("Failed to execute work successfully");
72              }
73          } catch (RuntimeException e) {
74              log.warn("RuntimeException occured while running user task", e);
75              throw e;
76          } catch (Error e) {
77              log.warn("Error occured while running user task", e);
78              throw e;
79          }
80      }
81  
82      private boolean beginWork() {
83          try {
84              transactionManager.begin();
85          } catch (Exception e) {
86              log.warn("Exception occured while starting container transaction", e);
87              return false;
88          }
89          return true;
90      }
91  
92      private void work() {
93          try {
94              userTask.run();
95          } catch (Exception e) {
96              log.warn("Exception occured while running user task", e);
97          }
98      }
99  
100     private boolean completeWork() {
101         try {
102             if (transactionManager.getStatus() == Status.STATUS_ACTIVE) {
103                 // clean up the work persistent data
104                 try {
105                     threadPooledTimer.workPerformed(workInfo);
106                 } catch (PersistenceException e) {
107                     log.warn("Exception occured while updating timer persistent state", e);
108                 }
109 
110                 // commit the tx
111                 transactionManager.commit();
112 
113                 // all is cool
114                 return true;
115             } else {
116                 // tx was marked rollback, so roll it back
117                 transactionManager.rollback();
118             }
119         } catch (Exception e) {
120             log.warn("Exception occured while completing container transaction", e);
121         }
122         // something bad happened
123         return false;
124     }
125 
126 }