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 skipGeneratedKeys; 040 041 boolean readOnly; 042 043 ArrayList<Class<? extends Throwable>> rollbackFor; 044 045 ArrayList<Class<? extends Throwable>> noRollbackFor; 046 047 /** 048 * Helper method to create a TxScope with REQUIRES. 049 */ 050 public static TxScope required() { 051 return new TxScope(TxType.REQUIRED); 052 } 053 054 /** 055 * Helper method to create a TxScope with REQUIRES_NEW. 056 */ 057 public static TxScope requiresNew() { 058 return new TxScope(TxType.REQUIRES_NEW); 059 } 060 061 /** 062 * Helper method to create a TxScope with MANDATORY. 063 */ 064 public static TxScope mandatory() { 065 return new TxScope(TxType.MANDATORY); 066 } 067 068 /** 069 * Helper method to create a TxScope with SUPPORTS. 070 */ 071 public static TxScope supports() { 072 return new TxScope(TxType.SUPPORTS); 073 } 074 075 /** 076 * Helper method to create a TxScope with NOT_SUPPORTED. 077 */ 078 public static TxScope notSupported() { 079 return new TxScope(TxType.NOT_SUPPORTED); 080 } 081 082 /** 083 * Helper method to create a TxScope with NEVER. 084 */ 085 public static TxScope never() { 086 return new TxScope(TxType.NEVER); 087 } 088 089 /** 090 * Create a REQUIRED transaction scope. 091 */ 092 public TxScope() { 093 this.type = TxType.REQUIRED; 094 } 095 096 /** 097 * Create with a given transaction scope type. 098 */ 099 public TxScope(TxType type) { 100 this.type = type; 101 } 102 103 /** 104 * Describes this TxScope instance. 105 */ 106 public String toString() { 107 return "TxScope[" + type + "] readOnly[" + readOnly + "] isolation[" + isolation 108 + "] serverName[" + serverName 109 + "] rollbackFor[" + rollbackFor + "] noRollbackFor[" + noRollbackFor + "]"; 110 } 111 112 /** 113 * Return true if PersistBatch has been set. 114 */ 115 public boolean isBatchSet() { 116 return batch != null && batch != PersistBatch.INHERIT; 117 } 118 119 /** 120 * Return true if batch on cascade has been set. 121 */ 122 public boolean isBatchOnCascadeSet() { 123 return batchOnCascade != null && batchOnCascade != PersistBatch.INHERIT; 124 } 125 126 /** 127 * Return true if batch size has been set. 128 */ 129 public boolean isBatchSizeSet() { 130 return batchSize > 0; 131 } 132 133 /** 134 * Check for batchSize being set without batch mode and use this to imply PersistBatch.ALL. 135 */ 136 public void checkBatchMode() { 137 if (batchSize > 0 && notSet(batch) && notSet(batchOnCascade)) { 138 // Use setting the batchSize as implying PersistBatch.ALL for @Transactional 139 batch = PersistBatch.ALL; 140 } 141 } 142 143 /** 144 * Return true if the mode is considered not set. 145 */ 146 private boolean notSet(PersistBatch batchMode) { 147 return batchMode == null || batchMode == PersistBatch.INHERIT; 148 } 149 150 /** 151 * Return the transaction type. 152 */ 153 public TxType getType() { 154 return type; 155 } 156 157 /** 158 * Set the transaction type. 159 */ 160 public TxScope setType(TxType type) { 161 this.type = type; 162 return this; 163 } 164 165 /** 166 * Return the batch mode. 167 */ 168 public PersistBatch getBatch() { 169 return batch; 170 } 171 172 /** 173 * Set the batch mode to use. 174 */ 175 public TxScope setBatch(PersistBatch batch) { 176 this.batch = batch; 177 return this; 178 } 179 180 /** 181 * Return the batch on cascade mode. 182 */ 183 public PersistBatch getBatchOnCascade() { 184 return batchOnCascade; 185 } 186 187 /** 188 * Set the batch on cascade mode. 189 */ 190 public TxScope setBatchOnCascade(PersistBatch batchOnCascade) { 191 this.batchOnCascade = batchOnCascade; 192 return this; 193 } 194 195 /** 196 * Return the batch size. 0 means use the default value. 197 */ 198 public int getBatchSize() { 199 return batchSize; 200 } 201 202 /** 203 * Set the batch size to use. 204 */ 205 public TxScope setBatchSize(int batchSize) { 206 this.batchSize = batchSize; 207 return this; 208 } 209 210 /** 211 * Set if the transaction should skip reading generated keys for inserts. 212 */ 213 public TxScope setSkipGeneratedKeys() { 214 this.skipGeneratedKeys = true; 215 return this; 216 } 217 218 /** 219 * Return true if getGeneratedKeys should be skipped for this transaction. 220 */ 221 public boolean isSkipGeneratedKeys() { 222 return skipGeneratedKeys; 223 } 224 225 /** 226 * Return if the transaction should be treated as read only. 227 */ 228 public boolean isReadonly() { 229 return readOnly; 230 } 231 232 /** 233 * Set if the transaction should be treated as read only. 234 */ 235 public TxScope setReadOnly(boolean readOnly) { 236 this.readOnly = readOnly; 237 return this; 238 } 239 240 /** 241 * Return the Isolation level this transaction should run with. 242 */ 243 public TxIsolation getIsolation() { 244 return isolation; 245 } 246 247 /** 248 * Set the transaction isolation level this transaction should run with. 249 */ 250 public TxScope setIsolation(TxIsolation isolation) { 251 this.isolation = isolation; 252 return this; 253 } 254 255 /** 256 * Return the serverName for this transaction. If this is null then the 257 * default server (default DataSource) will be used. 258 */ 259 public String getServerName() { 260 return serverName; 261 } 262 263 /** 264 * Set the serverName (DataSource name) for which this transaction will be. If 265 * the serverName is not specified (left null) then the default server will be 266 * used. 267 */ 268 public TxScope setServerName(String serverName) { 269 this.serverName = serverName; 270 return this; 271 } 272 273 /** 274 * Return the throwable's that should cause a rollback. 275 */ 276 public ArrayList<Class<? extends Throwable>> getRollbackFor() { 277 return rollbackFor; 278 } 279 280 /** 281 * Set a Throwable that should explicitly cause a rollback. 282 */ 283 public TxScope setRollbackFor(Class<? extends Throwable> rollbackThrowable) { 284 if (rollbackFor == null) { 285 rollbackFor = new ArrayList<Class<? extends Throwable>>(2); 286 } 287 rollbackFor.add(rollbackThrowable); 288 return this; 289 } 290 291 /** 292 * Set multiple throwable's that will cause a rollback. 293 */ 294 @SuppressWarnings("unchecked") 295 public TxScope setRollbackFor(Class<?>[] rollbackThrowables) { 296 if (rollbackFor == null) { 297 rollbackFor = new ArrayList<Class<? extends Throwable>>(rollbackThrowables.length); 298 } 299 for (int i = 0; i < rollbackThrowables.length; i++) { 300 rollbackFor.add((Class<? extends Throwable>) rollbackThrowables[i]); 301 } 302 return this; 303 } 304 305 /** 306 * Return the throwable's that should NOT cause a rollback. 307 */ 308 public ArrayList<Class<? extends Throwable>> getNoRollbackFor() { 309 return noRollbackFor; 310 } 311 312 /** 313 * Add a Throwable to a list that will NOT cause a rollback. You are able to 314 * call this method multiple times with different throwable's and they will 315 * added to a list. 316 */ 317 public TxScope setNoRollbackFor(Class<? extends Throwable> noRollback) { 318 if (noRollbackFor == null) { 319 noRollbackFor = new ArrayList<Class<? extends Throwable>>(2); 320 } 321 this.noRollbackFor.add(noRollback); 322 return this; 323 } 324 325 /** 326 * Set multiple throwable's that will NOT cause a rollback. 327 */ 328 @SuppressWarnings("unchecked") 329 public TxScope setNoRollbackFor(Class<?>[] noRollbacks) { 330 if (noRollbackFor == null) { 331 noRollbackFor = new ArrayList<Class<? extends Throwable>>(noRollbacks.length); 332 } 333 for (int i = 0; i < noRollbacks.length; i++) { 334 noRollbackFor.add((Class<? extends Throwable>) noRollbacks[i]); 335 } 336 return this; 337 } 338 339}