001package io.ebean.annotation;
002
003import java.lang.annotation.ElementType;
004import java.lang.annotation.Retention;
005import java.lang.annotation.RetentionPolicy;
006import java.lang.annotation.Target;
007
008/**
009 * Specify transaction scoping for a method.
010 * <p>
011 * <b><i> This is only supported if "Enhancement" is used via javaagent, ANT
012 * task or IDE enhancement plugin etc. </i></b>
013 * </p>
014 * <p>
015 * Note: Currently there are 3 known annotations that perform this role.
016 * <ul>
017 * <li>EJB's javax.ejb.TransactionAttribute</li>
018 * <li>Spring's org.springframework.transaction.annotation.Transactional</li>
019 * <li>and this one, Ebean's own Transactional</li>
020 * </ul>
021 * Spring created their one because the EJB annotation does not support features
022 * such as isolation level and specifying rollbackOn, noRollbackOn exceptions.
023 * This one exists for Ebean because I agree that the standard one is
024 * insufficient and don't want to include a dependency on Spring.
025 * </p>
026 * <p>
027 * The default behaviour of EJB (and hence Spring) is to NOT ROLLBACK on checked
028 * exceptions. I find this very counter-intuitive. Ebean will provide a property
029 * to set the default behaviour to rollback on any exception and optionally
030 * change the setting to be consistent with EJB/Spring if people wish to do so.
031 * </p>
032 * <p>
033 * <pre>{@code
034 *
035 *  // a normal class
036 *  public class MySimpleUserService {
037 *
038 *    // this method is transactional automatically handling
039 *    // transaction begin, commit and rollback etc
040 *    @Transactional
041 *    public void runInTrans() throws IOException {
042 *
043 *      // tasks performed within the transaction
044 *      ...
045 *      // find some objects
046 *      Customer cust = ebeanServer.find(Customer.class, 42);
047 *
048 *      Order order = ...;
049 *      ...
050 *      // save some objects
051 *      ebeanServer.save(customer);
052 *      ebeanServer.save(order);
053 *    }
054 *
055 * }</pre>
056 */
057@Target({ElementType.METHOD, ElementType.TYPE})
058@Retention(RetentionPolicy.RUNTIME)
059public @interface Transactional {
060
061  /**
062   * The type of transaction scoping. Defaults to REQUIRED.
063   */
064  TxType type() default TxType.REQUIRED;
065
066  /**
067   * Persist batch mode for the transaction.
068   */
069  PersistBatch batch() default PersistBatch.INHERIT;
070
071  /**
072   * Persist batch mode for the request if not set on the transaction.
073   * <p>
074   * If batch is set to NONE then batchOnCascade can be set to INSERT or ALL
075   * and then each save(), delete(), insert(), update() request that cascades
076   * to child beans can use JDBC batch.
077   * </p>
078   */
079  PersistBatch batchOnCascade() default PersistBatch.INHERIT;
080
081  /**
082   * The batch size to use when using JDBC batch mode.
083   * <p>
084   * If unset this defaults to the value set in ServerConfig.
085   * </p>
086   */
087  int batchSize() default 0;
088
089  /**
090   * Set to false when we want to skip getting generatedKeys.
091   * <p>
092   * This is typically used in the case of large batch inserts where we get a
093   * performance benefit from not calling getGeneratedKeys (as we are going to
094   * insert a lot of rows and have no need for the Id values after the insert).
095   * </p>
096   */
097  boolean getGeneratedKeys() default true;
098
099  /**
100   * The transaction isolation level this transaction should have.
101   * <p>
102   * This will only be used if this scope creates the transaction. If the
103   * transaction has already started then this will currently be ignored (you
104   * could argue that it should throw an exception).
105   * </p>
106   */
107  TxIsolation isolation() default TxIsolation.DEFAULT;
108
109  /**
110   * Set this to false if the JDBC batch should not be automatically flushed when a query is executed.
111   */
112  boolean flushOnQuery() default true;
113
114  /**
115   * Set this to true if the transaction should be only contain queries.
116   */
117  boolean readOnly() default false;
118
119  // int timeout() default 0;
120
121  /**
122   * Set this to true such that the L2 cache is not used by queries that otherwise would.
123   */
124  boolean skipCache() default false;
125
126  /**
127   * Set a label to identify the transaction in performance metrics and logging.
128   */
129  String label() default "";
130
131  /**
132   * The Throwable's that will explicitly cause a rollback to occur.
133   */
134  Class<? extends Throwable>[] rollbackFor() default {};
135
136  /**
137   * The Throwable's that will explicitly NOT cause a rollback to occur.
138   */
139  Class<? extends Throwable>[] noRollbackFor() default {};
140
141  /**
142   * A key used to identify a specific transaction for profiling purposes.
143   * <p>
144   * If set to -1 this means there should be no profiling on this transaction.
145   * </p>
146   * <p>
147   * If not set (left at 0) this means the profilingId can be automatically set during transactional enhancement.
148   * </p>
149   */
150  int profileId() default 0;
151}