001package com.avaje.ebean; 002 003import com.avaje.ebean.config.PersistBatch; 004 005import javax.persistence.PersistenceException; 006import javax.persistence.RollbackException; 007import java.io.Closeable; 008import java.sql.Connection; 009 010/** 011 * The Transaction object. Typically representing a JDBC or JTA transaction. 012 */ 013public interface Transaction extends Closeable { 014 015 /** 016 * Read Committed transaction isolation. Same as 017 * java.sql.Connection.TRANSACTION_READ_COMMITTED. 018 */ 019 int READ_COMMITTED = java.sql.Connection.TRANSACTION_READ_COMMITTED; 020 021 /** 022 * Read Uncommitted transaction isolation. Same as 023 * java.sql.Connection.TRANSACTION_READ_UNCOMMITTED. 024 */ 025 int READ_UNCOMMITTED = java.sql.Connection.TRANSACTION_READ_UNCOMMITTED; 026 027 /** 028 * Repeatable read transaction isolation. Same as 029 * java.sql.Connection.TRANSACTION_REPEATABLE_READ. 030 */ 031 int REPEATABLE_READ = java.sql.Connection.TRANSACTION_REPEATABLE_READ; 032 033 /** 034 * Serializable transaction isolation. Same as 035 * java.sql.Connection.TRANSACTION_SERIALIZABLE. 036 */ 037 int SERIALIZABLE = java.sql.Connection.TRANSACTION_SERIALIZABLE; 038 039 /** 040 * Register a TransactionCallback with this transaction. 041 */ 042 void register(TransactionCallback callback); 043 044 /** 045 * Return true if this transaction is read only. 046 */ 047 boolean isReadOnly(); 048 049 /** 050 * Set whether this transaction should be readOnly. 051 */ 052 void setReadOnly(boolean readOnly); 053 054 /** 055 * Commit the transaction. 056 */ 057 void commit() throws RollbackException; 058 059 /** 060 * Rollback the transaction. 061 */ 062 void rollback() throws PersistenceException; 063 064 /** 065 * Rollback the transaction specifying a throwable that caused the rollback to 066 * occur. 067 * <p> 068 * If you are using transaction logging this will log the throwable in the 069 * transaction logs. 070 * </p> 071 */ 072 void rollback(Throwable e) throws PersistenceException; 073 074 /** 075 * If the transaction is active then perform rollback. Otherwise do nothing. 076 */ 077 void end() throws PersistenceException; 078 079 /** 080 * Return true if the transaction is active. 081 */ 082 boolean isActive(); 083 084 /** 085 * Explicitly turn off or on the cascading nature of save() and delete(). This 086 * gives the developer exact control over what beans are saved and deleted 087 * rather than Ebean cascading detecting 'dirty/modified' beans etc. 088 * <p> 089 * This is useful if you can getting back entity beans from a layer of code 090 * (potentially remote) and you prefer to have exact control. 091 * </p> 092 * <p> 093 * This may also be useful if you are using jdbc batching with jdbc drivers 094 * that do not support getGeneratedKeys. 095 * </p> 096 */ 097 void setPersistCascade(boolean persistCascade); 098 099 /** 100 * Set to true when you want all loaded properties to be included in the update 101 * (rather than just the changed properties). 102 * <p> 103 * You might set this when using JDBC batch in order to get multiple updates 104 * with slightly different sets of changed properties into the same statement 105 * and hence better JDBC batch performance. 106 * </p> 107 */ 108 void setUpdateAllLoadedProperties(boolean updateAllLoadedProperties); 109 110 /** 111 * Turn on or off statement batching. Statement batching can be transparent 112 * for drivers and databases that support getGeneratedKeys. Otherwise you may 113 * wish to specifically control when batching is used via this method. 114 * <p> 115 * Refer to <code>java.sql.PreparedStatement.addBatch();</code> 116 * <p> 117 * Note that you may also wish to use the setPersistCascade method to stop 118 * save and delete cascade behaviour. You may do this to have full control 119 * over the order of execution rather than the normal cascading fashion. 120 * </p> 121 * <p> 122 * Note that the <em>execution order</em> in batch mode may be different from 123 * non batch mode execution order. Also note that <em>insert behaviour</em> 124 * may be different depending on the JDBC driver and its support for 125 * getGeneratedKeys. That is, for JDBC drivers that do not support 126 * getGeneratedKeys you may not get back the generated IDs (used for inserting 127 * associated detail beans etc). 128 * </p> 129 * <p> 130 * Calls to save(), delete(), insert() and execute() all support batch 131 * processing. This includes normal beans, MapBean, CallableSql and UpdateSql. 132 * </p> 133 * <p> 134 * The flushing of the batched statements is automatic but you can call 135 * batchFlush when you like. Note that flushing occurs when a query is 136 * executed or when you mix UpdateSql and CallableSql with save and delete of 137 * beans. 138 * </p> 139 * <p> 140 * Example: batch processing executing every 3 rows 141 * </p> 142 * 143 * <pre>{@code 144 * 145 * String data = "This is a simple test of the batch processing" 146 * + " mode and the transaction execute batch method"; 147 * 148 * String[] da = data.split(" "); 149 * 150 * String sql = "{call sp_t3(?,?)}"; 151 * 152 * CallableSql cs = new CallableSql(sql); 153 * cs.registerOut(2, Types.INTEGER); 154 * 155 * // (optional) inform eBean this stored procedure 156 * // inserts into a table called sp_test 157 * cs.addModification("sp_test", true, false, false); 158 * 159 * Transaction txn = ebeanServer.beginTransaction(); 160 * txn.setBatchMode(true); 161 * txn.setBatchSize(3); 162 * try { 163 * for (int i = 0; i < da.length;) { 164 * cs.setParameter(1, da[i]); 165 * ebeanServer.execute(cs); 166 * } 167 * 168 * // NB: commit implicitly flushes 169 * txn.commit(); 170 * 171 * } finally { 172 * txn.end(); 173 * } 174 * 175 * }</pre> 176 * 177 */ 178 void setBatchMode(boolean useBatch); 179 180 /** 181 * The JDBC batch mode to use for this transaction. 182 * <p> 183 * If this is NONE then JDBC batch can still be used for each request - save(), insert(), update() or delete() 184 * and this would be useful if the request cascades to detail beans. 185 * </p> 186 * 187 * @param persistBatchMode the batch mode to use for this transaction 188 * 189 * @see com.avaje.ebean.config.ServerConfig#setPersistBatch(com.avaje.ebean.config.PersistBatch) 190 */ 191 void setBatch(PersistBatch persistBatchMode); 192 193 /** 194 * Return the batch mode at the transaction level. 195 */ 196 PersistBatch getBatch(); 197 198 /** 199 * Set the JDBC batch mode to use for a save() or delete() request. 200 * <p> 201 * This only takes effect when batch mode on the transaction has not already meant that 202 * JDBC batch mode is being used. 203 * </p> 204 * <p> 205 * This is useful when the single save() or delete() cascades. For example, inserting a 'master' cascades 206 * and inserts a collection of 'detail' beans. The detail beans can be inserted using JDBC batch. 207 * </p> 208 * 209 * @param batchOnCascadeMode the batch mode to use per save(), insert(), update() or delete() 210 * 211 * @see com.avaje.ebean.config.ServerConfig#setPersistBatchOnCascade(com.avaje.ebean.config.PersistBatch) 212 */ 213 void setBatchOnCascade(PersistBatch batchOnCascadeMode); 214 215 /** 216 * Return the batch mode at the request level (for each save(), insert(), update() or delete()). 217 */ 218 PersistBatch getBatchOnCascade(); 219 220 /** 221 * Specify the number of statements before a batch is flushed automatically. 222 */ 223 void setBatchSize(int batchSize); 224 225 /** 226 * Return the current batch size. 227 */ 228 int getBatchSize(); 229 230 /** 231 * Specify if you want batched inserts to use getGeneratedKeys. 232 * <p> 233 * By default batched inserts will try to use getGeneratedKeys if it is 234 * supported by the underlying jdbc driver and database. 235 * </p> 236 * <p> 237 * You may want to turn getGeneratedKeys off when you are inserting a large 238 * number of objects and you don't care about getting back the ids. 239 * </p> 240 */ 241 void setBatchGetGeneratedKeys(boolean getGeneratedKeys); 242 243 /** 244 * By default when mixing UpdateSql (or CallableSql) with Beans the batch is 245 * automatically flushed when you change (between persisting beans and 246 * executing UpdateSql or CallableSql). 247 * <p> 248 * If you want to execute both WITHOUT having the batch automatically flush 249 * you need to call this with batchFlushOnMixed = false. 250 * </p> 251 * <p> 252 * Note that UpdateSql and CallableSql are ALWAYS executed first (before the 253 * beans are executed). This is because the UpdateSql and CallableSql have 254 * already been bound to their PreparedStatements. The beans on the other hand 255 * have a 2 step process (delayed binding). 256 * </p> 257 */ 258 void setBatchFlushOnMixed(boolean batchFlushOnMixed); 259 260 /** 261 * By default executing a query will automatically flush any batched 262 * statements (persisted beans, executed UpdateSql etc). 263 * <p> 264 * Calling this method with batchFlushOnQuery = false means that you can 265 * execute a query and the batch will not be automatically flushed. 266 * </p> 267 */ 268 void setBatchFlushOnQuery(boolean batchFlushOnQuery); 269 270 /** 271 * Return true if the batch (of persisted beans or executed UpdateSql etc) 272 * should be flushed prior to executing a query. 273 * <p> 274 * The default is for this to be true. 275 * </p> 276 */ 277 boolean isBatchFlushOnQuery(); 278 279 /** 280 * The batch will be flushing automatically but you can use this to explicitly 281 * flush the batch if you like. 282 * <p> 283 * Flushing occurs automatically when: 284 * </p> 285 * <ul> 286 * <li>the batch size is reached</li> 287 * <li>A query is executed on the same transaction</li> 288 * <li>UpdateSql or CallableSql are mixed with bean save and delete</li> 289 * <li>Transaction commit occurs</li> 290 * </ul> 291 */ 292 void flushBatch() throws PersistenceException; 293 294 /** 295 * Return the underlying Connection object. 296 * <p> 297 * Useful where a Developer wishes to use the JDBC API directly. Note that the 298 * commit() rollback() and end() methods on the Transaction should still be 299 * used. Calling these methods on the Connection would be a big no no unless 300 * you know what you are doing. 301 * </p> 302 * <p> 303 * Examples of when a developer may wish to use the connection directly are: 304 * Savepoints, advanced CLOB BLOB use and advanced stored procedure calls. 305 * </p> 306 */ 307 Connection getConnection(); 308 309 /** 310 * Add table modification information to the TransactionEvent. 311 * <p> 312 * Use this in conjunction with getConnection() and raw JDBC. 313 * </p> 314 * <p> 315 * This effectively informs Ebean of the data that has been changed by the 316 * transaction and this information is normally automatically handled by Ebean 317 * when you save entity beans or use UpdateSql etc. 318 * </p> 319 * <p> 320 * If you use raw JDBC then you can use this method to inform Ebean for the 321 * tables that have been modified. Ebean uses this information to keep its 322 * caches in synch and maintain text indexes. 323 * </p> 324 */ 325 void addModification(String tableName, boolean inserts, boolean updates, boolean deletes); 326 327 /** 328 * Add an arbitrary user object to the transaction. The objects added have no 329 * impact on any internals of ebena and are solely meant as a convenient 330 * method push user information to e.g. the 331 * {@link com.avaje.ebean.event.TransactionEventListener}. 332 */ 333 void putUserObject(String name, Object value); 334 335 /** 336 * Get an object added with {@link #putUserObject(String, Object)}. 337 */ 338 Object getUserObject(String name); 339}