001package com.avaje.ebean;
002
003import com.avaje.ebean.config.PersistBatch;
004
005import java.util.ArrayList;
006
007/**
008 * Holds the definition of how a transactional method should run.
009 * <p>
010 * This information matches the features of the Transactional annotation. You
011 * can use it directly with TxRunnable or TxCallable via
012 * {@link Ebean#execute(TxScope, TxCallable)} or
013 * {@link Ebean#execute(TxScope, TxRunnable)}.
014 * </p>
015 * <p>
016 * This object is used internally with the enhancement of a method with
017 * Transactional annotation.
018 * </p>
019 * 
020 * @see TxCallable
021 * @see TxRunnable
022 * @see Ebean#execute(TxScope, TxCallable)
023 * @see Ebean#execute(TxScope, TxRunnable)
024 */
025public final class TxScope {
026
027  TxType type;
028
029  String serverName;
030
031  TxIsolation isolation;
032
033  PersistBatch batch;
034
035  PersistBatch batchOnCascade;
036
037  int batchSize;
038
039  boolean readOnly;
040
041  ArrayList<Class<? extends Throwable>> rollbackFor;
042
043  ArrayList<Class<? extends Throwable>> noRollbackFor;
044
045  /**
046   * Return true if PersistBatch has been set.
047   */
048  public boolean isBatchSet() {
049    return batch != null && batch != PersistBatch.INHERIT;
050  }
051
052  /**
053   * Return true if batch on cascade has been set.
054   */
055  public boolean isBatchOnCascadeSet() {
056    return batchOnCascade != null && batchOnCascade != PersistBatch.INHERIT;
057  }
058
059  /**
060   * Return true if batch size has been set.
061   */
062  public boolean isBatchSizeSet() {
063    return batchSize > 0;
064  }
065
066  /**
067   * Helper method to create a TxScope with REQUIRES.
068   */
069  public static TxScope required() {
070    return new TxScope(TxType.REQUIRED);
071  }
072
073  /**
074   * Helper method to create a TxScope with REQUIRES_NEW.
075   */
076  public static TxScope requiresNew() {
077    return new TxScope(TxType.REQUIRES_NEW);
078  }
079
080  /**
081   * Helper method to create a TxScope with MANDATORY.
082   */
083  public static TxScope mandatory() {
084    return new TxScope(TxType.MANDATORY);
085  }
086
087  /**
088   * Helper method to create a TxScope with SUPPORTS.
089   */
090  public static TxScope supports() {
091    return new TxScope(TxType.SUPPORTS);
092  }
093
094  /**
095   * Helper method to create a TxScope with NOT_SUPPORTED.
096   */
097  public static TxScope notSupported() {
098    return new TxScope(TxType.NOT_SUPPORTED);
099  }
100
101  /**
102   * Helper method to create a TxScope with NEVER.
103   */
104  public static TxScope never() {
105    return new TxScope(TxType.NEVER);
106  }
107
108  /**
109   * Create a REQUIRED transaction scope.
110   */
111  public TxScope() {
112    this.type = TxType.REQUIRED;
113  }
114
115  /**
116   * Create with a given transaction scope type.
117   */
118  public TxScope(TxType type) {
119    this.type = type;
120  }
121
122  /**
123   * Describes this TxScope instance.
124   */
125  public String toString() {
126    return "TxScope[" + type + "] readOnly[" + readOnly + "] isolation[" + isolation
127        + "] serverName[" + serverName
128        + "] rollbackFor[" + rollbackFor + "] noRollbackFor[" + noRollbackFor + "]";
129  }
130
131  /**
132   * Return the transaction type.
133   */
134  public TxType getType() {
135    return type;
136  }
137
138  /**
139   * Set the transaction type.
140   */
141  public TxScope setType(TxType type) {
142    this.type = type;
143    return this;
144  }
145
146  /**
147   * Return the batch mode.
148   */
149  public PersistBatch getBatch() {
150    return batch;
151  }
152
153  /**
154   * Set the batch mode to use.
155   */
156  public TxScope setBatch(PersistBatch batch) {
157    this.batch = batch;
158    return this;
159  }
160
161  /**
162   * Return the batch on cascade mode.
163   */
164  public PersistBatch getBatchOnCascade() {
165    return batchOnCascade;
166  }
167
168  /**
169   * Set the batch on cascade mode.
170   */
171  public TxScope setBatchOnCascade(PersistBatch batchOnCascade) {
172    this.batchOnCascade = batchOnCascade;
173    return this;
174  }
175
176  /**
177   * Return the batch size. 0 means use the default value.
178   */
179  public int getBatchSize() {
180    return batchSize;
181  }
182
183  /**
184   * Set the batch size to use.
185   */
186  public TxScope setBatchSize(int batchSize) {
187    this.batchSize = batchSize;
188    return this;
189  }
190
191  /**
192   * Return if the transaction should be treated as read only.
193   */
194  public boolean isReadonly() {
195    return readOnly;
196  }
197
198  /**
199   * Set if the transaction should be treated as read only.
200   */
201  public TxScope setReadOnly(boolean readOnly) {
202    this.readOnly = readOnly;
203    return this;
204  }
205
206  /**
207   * Return the Isolation level this transaction should run with.
208   */
209  public TxIsolation getIsolation() {
210    return isolation;
211  }
212
213  /**
214   * Set the transaction isolation level this transaction should run with.
215   */
216  public TxScope setIsolation(TxIsolation isolation) {
217    this.isolation = isolation;
218    return this;
219  }
220
221  /**
222   * Return the serverName for this transaction. If this is null then the
223   * default server (default DataSource) will be used.
224   */
225  public String getServerName() {
226    return serverName;
227  }
228
229  /**
230   * Set the serverName (DataSource name) for which this transaction will be. If
231   * the serverName is not specified (left null) then the default server will be
232   * used.
233   */
234  public TxScope setServerName(String serverName) {
235    this.serverName = serverName;
236    return this;
237  }
238
239  /**
240   * Return the throwable's that should cause a rollback.
241   */
242  public ArrayList<Class<? extends Throwable>> getRollbackFor() {
243    return rollbackFor;
244  }
245
246  /**
247   * Set a Throwable that should explicitly cause a rollback.
248   */
249  public TxScope setRollbackFor(Class<? extends Throwable> rollbackThrowable) {
250    if (rollbackFor == null) {
251      rollbackFor = new ArrayList<Class<? extends Throwable>>(2);
252    }
253    rollbackFor.add(rollbackThrowable);
254    return this;
255  }
256
257  /**
258   * Set multiple throwable's that will cause a rollback.
259   */
260  @SuppressWarnings("unchecked")
261  public TxScope setRollbackFor(Class<?>[] rollbackThrowables) {
262    if (rollbackFor == null) {
263      rollbackFor = new ArrayList<Class<? extends Throwable>>(rollbackThrowables.length);
264    }
265    for (int i = 0; i < rollbackThrowables.length; i++) {
266      rollbackFor.add((Class<? extends Throwable>) rollbackThrowables[i]);
267    }
268    return this;
269  }
270
271  /**
272   * Return the throwable's that should NOT cause a rollback.
273   */
274  public ArrayList<Class<? extends Throwable>> getNoRollbackFor() {
275    return noRollbackFor;
276  }
277
278  /**
279   * Add a Throwable to a list that will NOT cause a rollback. You are able to
280   * call this method multiple times with different throwable's and they will
281   * added to a list.
282   */
283  public TxScope setNoRollbackFor(Class<? extends Throwable> noRollback) {
284    if (noRollbackFor == null) {
285      noRollbackFor = new ArrayList<Class<? extends Throwable>>(2);
286    }
287    this.noRollbackFor.add(noRollback);
288    return this;
289  }
290
291  /**
292   * Set multiple throwable's that will NOT cause a rollback.
293   */
294  @SuppressWarnings("unchecked")
295  public TxScope setNoRollbackFor(Class<?>[] noRollbacks) {
296    if (noRollbackFor == null) {
297      noRollbackFor = new ArrayList<Class<? extends Throwable>>(noRollbacks.length);
298    }
299    for (int i = 0; i < noRollbacks.length; i++) {
300      noRollbackFor.add((Class<? extends Throwable>) noRollbacks[i]);
301    }
302    return this;
303  }
304
305}