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