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}