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
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
65 if (workInfo.isOneTime()) {
66 threadPooledTimer.removeWorkInfo(workInfo);
67 }
68
69
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
104 try {
105 threadPooledTimer.workPerformed(workInfo);
106 } catch (PersistenceException e) {
107 log.warn("Exception occured while updating timer persistent state", e);
108 }
109
110
111 transactionManager.commit();
112
113
114 return true;
115 } else {
116
117 transactionManager.rollback();
118 }
119 } catch (Exception e) {
120 log.warn("Exception occured while completing container transaction", e);
121 }
122
123 return false;
124 }
125
126 }