001package io.ebean; 002 003import io.ebean.annotation.DocStoreMode; 004import io.ebean.annotation.PersistBatch; 005import io.ebean.config.DocStoreConfig; 006import io.ebean.config.ServerConfig; 007 008import javax.persistence.PersistenceException; 009import java.sql.Connection; 010 011/** 012 * The Transaction object. Typically representing a JDBC or JTA transaction. 013 */ 014public interface Transaction extends AutoCloseable { 015 016 /** 017 * Return the current transaction (of the default database) or null if there is 018 * no current transaction in scope. 019 * <p> 020 * This is the same as <code>DB.currentTransaction()</code> 021 * </p> 022 * <p> 023 * This returns the current transaction for the 'default server'. If you are using 024 * multiple EbeanServer's then use {@link DB#currentTransaction()}. 025 * </p> 026 * 027 * @see DB#currentTransaction() 028 * @see Database#currentTransaction() 029 */ 030 static Transaction current() { 031 return Ebean.currentTransaction(); 032 } 033 034 /** 035 * Read Committed transaction isolation. Same as 036 * java.sql.Connection.TRANSACTION_READ_COMMITTED. 037 */ 038 int READ_COMMITTED = java.sql.Connection.TRANSACTION_READ_COMMITTED; 039 040 /** 041 * Read Uncommitted transaction isolation. Same as 042 * java.sql.Connection.TRANSACTION_READ_UNCOMMITTED. 043 */ 044 int READ_UNCOMMITTED = java.sql.Connection.TRANSACTION_READ_UNCOMMITTED; 045 046 /** 047 * Repeatable read transaction isolation. Same as 048 * java.sql.Connection.TRANSACTION_REPEATABLE_READ. 049 */ 050 int REPEATABLE_READ = java.sql.Connection.TRANSACTION_REPEATABLE_READ; 051 052 /** 053 * Serializable transaction isolation. Same as 054 * java.sql.Connection.TRANSACTION_SERIALIZABLE. 055 */ 056 int SERIALIZABLE = java.sql.Connection.TRANSACTION_SERIALIZABLE; 057 058 /** 059 * Register a TransactionCallback with this transaction. 060 */ 061 void register(TransactionCallback callback); 062 063 /** 064 * Set a label on the transaction. 065 * <p> 066 * This label is used to group transaction execution times for performance metrics reporting. 067 * </p> 068 */ 069 void setLabel(String label); 070 071 /** 072 * Return true if this transaction is read only. 073 */ 074 boolean isReadOnly(); 075 076 /** 077 * Set whether this transaction should be readOnly. 078 */ 079 void setReadOnly(boolean readOnly); 080 081 /** 082 * Commits the transaction at this point with the expectation that another 083 * commit (or rollback or end) will occur later to complete the transaction. 084 * <p> 085 * This is similar to commit() but leaves the transaction "Active". 086 * </p> 087 * <h3>Functions</h3> 088 * <ul> 089 * <li>Flush the JDBC batch buffer</li> 090 * <li>Call commit on the underlying JDBC connection</li> 091 * <li>Trigger any registered TransactionCallbacks</li> 092 * <li>Perform post-commit processing updating L2 cache, ElasticSearch etc</li> 093 * </ul> 094 */ 095 void commitAndContinue(); 096 097 /** 098 * Commit the transaction. 099 * <p> 100 * This performs commit and completes the transaction closing underlying resources and 101 * marking the transaction as "In active". 102 * </p> 103 * <h3>Functions</h3> 104 * <ul> 105 * <li>Flush the JDBC batch buffer</li> 106 * <li>Call commit on the underlying JDBC connection</li> 107 * <li>Trigger any registered TransactionCallbacks</li> 108 * <li>Perform post-commit processing updating L2 cache, ElasticSearch etc</li> 109 * <li>Close any underlying resources, closing the underlying JDBC connection</li> 110 * <li>Mark the transaction as "Inactive"</li> 111 * </ul> 112 */ 113 void commit(); 114 115 /** 116 * Rollback the transaction. 117 * <p> 118 * This performs rollback, closes underlying resources and marks the transaction as "In active". 119 * </p> 120 * <h3>Functions</h3> 121 * <ul> 122 * <li>Call rollback on the underlying JDBC connection</li> 123 * <li>Trigger any registered TransactionCallbacks</li> 124 * <li>Close any underlying resources, closing the underlying JDBC connection</li> 125 * <li>Mark the transaction as "Inactive"</li> 126 * </ul> 127 */ 128 void rollback() throws PersistenceException; 129 130 /** 131 * Rollback the transaction specifying a throwable that caused the rollback to 132 * occur. 133 * <p> 134 * If you are using transaction logging this will log the throwable in the 135 * transaction logs. 136 * </p> 137 */ 138 void rollback(Throwable e) throws PersistenceException; 139 140 /** 141 * Set when we want nested transactions to use Savepoint's. 142 * <p> 143 * This means that for a nested transaction: 144 * <ul> 145 * <li>begin transaction maps to creating a savepoint</li> 146 * <li>commit transaction maps to releasing a savepoint</li> 147 * <li>rollback transaction maps to rollback a savepoint</li> 148 * </ul> 149 */ 150 void setNestedUseSavepoint(); 151 152 /** 153 * Mark the transaction for rollback only. 154 */ 155 void setRollbackOnly(); 156 157 /** 158 * Return true if the transaction is marked as rollback only. 159 */ 160 boolean isRollbackOnly(); 161 162 /** 163 * If the transaction is active then perform rollback. Otherwise do nothing. 164 */ 165 void end(); 166 167 /** 168 * Synonym for end() to support AutoClosable. 169 */ 170 @Override 171 void close(); 172 173 /** 174 * Return true if the transaction is active. 175 */ 176 boolean isActive(); 177 178 /** 179 * Set the behavior for document store updates on this transaction. 180 * <p> 181 * For example, set the mode to DocStoreEvent.IGNORE for this transaction and 182 * then any changes via this transaction are not sent to the doc store. This 183 * would be used when doing large bulk inserts into the database and we want 184 * to control how that is sent to the document store. 185 * </p> 186 */ 187 void setDocStoreMode(DocStoreMode mode); 188 189 /** 190 * Set the batch size to use for sending messages to the document store. 191 * <p> 192 * You might set this if you know the changes in this transaction result in especially large or 193 * especially small payloads and want to adjust the batch size to match. 194 * </p> 195 * <p> 196 * Setting this overrides the default of {@link DocStoreConfig#getBulkBatchSize()} 197 * </p> 198 */ 199 void setDocStoreBatchSize(int batchSize); 200 201 /** 202 * Explicitly turn off or on the cascading nature of save() and delete(). This 203 * gives the developer exact control over what beans are saved and deleted 204 * rather than Ebean cascading detecting 'dirty/modified' beans etc. 205 * <p> 206 * This is useful if you can getting back entity beans from a layer of code 207 * (potentially remote) and you prefer to have exact control. 208 * </p> 209 * <p> 210 * This may also be useful if you are using jdbc batching with jdbc drivers 211 * that do not support getGeneratedKeys. 212 * </p> 213 */ 214 void setPersistCascade(boolean persistCascade); 215 216 /** 217 * Set to true when you want all loaded properties to be included in the update 218 * (rather than just the changed properties). 219 * <p> 220 * You might set this when using JDBC batch in order to get multiple updates 221 * with slightly different sets of changed properties into the same statement 222 * and hence better JDBC batch performance. 223 * </p> 224 */ 225 void setUpdateAllLoadedProperties(boolean updateAllLoadedProperties); 226 227 /** 228 * Set if the L2 cache should be skipped for "find by id" and "find by natural key" queries. 229 * <p> 230 * By default {@link ServerConfig#isSkipCacheAfterWrite()} is true and that means that for 231 * "find by id" and "find by natural key" queries which normally hit L2 bean cache automatically 232 * - will not do so after a persist/write on the transaction. 233 * </p> 234 * <p> 235 * This method provides explicit control over whether "find by id" and "find by natural key" 236 * will skip the L2 bean cache or not (regardless of whether the transaction is considered "read only"). 237 * </p> 238 * <p> 239 * Refer to {@link ServerConfig#setSkipCacheAfterWrite(boolean)} for configuring the default behavior 240 * for using the L2 bean cache in transactions spanning multiple query/persist requests. 241 * </p> 242 * 243 * <pre>{@code 244 * 245 * // assume Customer has L2 bean caching enabled ... 246 * 247 * try (Transaction transaction = DB.beginTransaction()) { 248 * 249 * // this uses L2 bean cache as the transaction 250 * // ... is considered "query only" at this point 251 * Customer.find.byId(42); 252 * 253 * // transaction no longer "query only" once 254 * // ... a bean has been saved etc 255 * someBean.save(); 256 * 257 * // will NOT use L2 bean cache as the transaction 258 * // ... is no longer considered "query only" 259 * Customer.find.byId(55); 260 * 261 * 262 * 263 * // explicit control - please use L2 bean cache 264 * 265 * transaction.setSkipCache(false); 266 * Customer.find.byId(77); // hit the l2 bean cache 267 * 268 * 269 * // explicit control - please don't use L2 bean cache 270 * 271 * transaction.setSkipCache(true); 272 * Customer.find.byId(99); // skips l2 bean cache 273 * 274 * 275 * transaction.commit(); 276 * } 277 * 278 * }</pre> 279 * 280 * @see ServerConfig#isSkipCacheAfterWrite() 281 */ 282 void setSkipCache(boolean skipCache); 283 284 /** 285 * Return true if the L2 cache should be skipped. More accurately if true then find by id 286 * and find by natural key queries should NOT automatically use the L2 bean cache. 287 */ 288 boolean isSkipCache(); 289 290 /** 291 * Turn on or off use of JDBC statement batching. 292 * <p> 293 * Calls to save(), delete(), insert() and execute() all support batch 294 * processing. This includes normal beans, CallableSql and UpdateSql. 295 * </p> 296 * 297 * <pre>{@code 298 * 299 * try (Transaction transaction = server.beginTransaction()) { 300 * 301 * // turn on JDBC batch 302 * transaction.setBatchMode(true); 303 * 304 * // tune the batch size 305 * transaction.setBatchSize(50); 306 * 307 * ... 308 * 309 * transaction.commit(); 310 * } 311 * 312 * }</pre> 313 * 314 * <h3>getGeneratedKeys</h3> 315 * <p> 316 * Often with large batch inserts we want to turn off getGeneratedKeys. We do 317 * this via {@link #setBatchGetGeneratedKeys(boolean)}. 318 * Also note that some JDBC drivers do not support getGeneratedKeys in JDBC batch mode. 319 * </p> 320 * <pre>{@code 321 * 322 * try (Transaction transaction = server.beginTransaction()) { 323 * 324 * transaction.setBatchMode(true); 325 * transaction.setBatchSize(100); 326 * // insert but don't bother getting back the generated keys 327 * transaction.setBatchGetGeneratedKeys(false); 328 * 329 * 330 * // perform lots of inserts ... 331 * ... 332 * 333 * transaction.commit(); 334 * } 335 * 336 * }</pre> 337 * 338 * <h3>Flush</h3> 339 * <p> 340 * The batch is automatically flushed when it hits the batch size and also when we 341 * execute queries or when we mix UpdateSql and CallableSql with save and delete of 342 * beans. 343 * </p> 344 * <p> 345 * We use {@link #flush()} to explicitly flush the batch and we can use 346 * {@link #setBatchFlushOnQuery(boolean)} and {@link #setBatchFlushOnMixed(boolean)} 347 * to control the automatic flushing behaviour. 348 * </p> 349 * <p> 350 * Example: batch processing of CallableSql executing every 10 rows 351 * </p> 352 * 353 * <pre>{@code 354 * 355 * String data = "This is a simple test of the batch processing" 356 * + " mode and the transaction execute batch method"; 357 * 358 * String[] da = data.split(" "); 359 * 360 * String sql = "{call sp_t3(?,?)}"; 361 * 362 * CallableSql cs = new CallableSql(sql); 363 * cs.registerOut(2, Types.INTEGER); 364 * 365 * // (optional) inform Ebean this stored procedure 366 * // inserts into a table called sp_test 367 * cs.addModification("sp_test", true, false, false); 368 * 369 * try (Transaction txn = DB.beginTransaction()) { 370 * txn.setBatchMode(true); 371 * txn.setBatchSize(10); 372 * 373 * for (int i = 0; i < da.length;) { 374 * cs.setParameter(1, da[i]); 375 * DB.execute(cs); 376 * } 377 * 378 * // Note: commit implicitly flushes 379 * txn.commit(); 380 * } 381 * 382 * }</pre> 383 */ 384 void setBatchMode(boolean useBatch); 385 386 /** 387 * Return the batch mode at the transaction level. 388 */ 389 boolean isBatchMode(); 390 391 /** 392 * Set the JDBC batch mode to use for a save() or delete() when cascading to children. 393 * <p> 394 * This only takes effect when batch mode on the transaction has not already meant that 395 * JDBC batch mode is being used. 396 * </p> 397 * <p> 398 * This is useful when the single save() or delete() cascades. For example, inserting a 'master' cascades 399 * and inserts a collection of 'detail' beans. The detail beans can be inserted using JDBC batch. 400 * </p> 401 * <p> 402 * This is effectively already turned on for all platforms apart from older Sql Server. 403 * </p> 404 * 405 * @param batchMode the batch mode to use per save(), insert(), update() or delete() 406 * @see io.ebean.config.ServerConfig#setPersistBatchOnCascade(PersistBatch) 407 */ 408 void setBatchOnCascade(boolean batchMode); 409 410 /** 411 * Return the batch mode at the request level. 412 */ 413 boolean isBatchOnCascade(); 414 415 /** 416 * Specify the number of statements before a batch is flushed automatically. 417 */ 418 void setBatchSize(int batchSize); 419 420 /** 421 * Return the current batch size. 422 */ 423 int getBatchSize(); 424 425 /** 426 * Specify if you want batched inserts to use getGeneratedKeys. 427 * <p> 428 * By default batched inserts will try to use getGeneratedKeys if it is 429 * supported by the underlying jdbc driver and database. 430 * </p> 431 * <p> 432 * You may want to turn getGeneratedKeys off when you are inserting a large 433 * number of objects and you don't care about getting back the ids. 434 * </p> 435 */ 436 void setBatchGetGeneratedKeys(boolean getGeneratedKeys); 437 438 /** 439 * By default when mixing UpdateSql (or CallableSql) with Beans the batch is 440 * automatically flushed when you change (between persisting beans and 441 * executing UpdateSql or CallableSql). 442 * <p> 443 * If you want to execute both WITHOUT having the batch automatically flush 444 * you need to call this with batchFlushOnMixed = false. 445 * </p> 446 * <p> 447 * Note that UpdateSql and CallableSql are ALWAYS executed first (before the 448 * beans are executed). This is because the UpdateSql and CallableSql have 449 * already been bound to their PreparedStatements. The beans on the other hand 450 * have a 2 step process (delayed binding). 451 * </p> 452 */ 453 void setBatchFlushOnMixed(boolean batchFlushOnMixed); 454 455 /** 456 * By default executing a query will automatically flush any batched 457 * statements (persisted beans, executed UpdateSql etc). 458 * <p> 459 * Calling this method with batchFlushOnQuery = false means that you can 460 * execute a query and the batch will not be automatically flushed. 461 * </p> 462 */ 463 void setBatchFlushOnQuery(boolean batchFlushOnQuery); 464 465 /** 466 * Return true if the batch (of persisted beans or executed UpdateSql etc) 467 * should be flushed prior to executing a query. 468 * <p> 469 * The default is for this to be true. 470 * </p> 471 */ 472 boolean isBatchFlushOnQuery(); 473 474 /** 475 * The batch will be flushing automatically but you can use this to explicitly 476 * flush the batch if you like. 477 * <p> 478 * Flushing occurs automatically when: 479 * </p> 480 * <ul> 481 * <li>the batch size is reached</li> 482 * <li>A query is executed on the same transaction</li> 483 * <li>UpdateSql or CallableSql are mixed with bean save and delete</li> 484 * <li>Transaction commit occurs</li> 485 * <li>A getter method is called on a batched bean</li> 486 * </ul> 487 */ 488 void flush() throws PersistenceException; 489 490 /** 491 * This is a synonym for flush() and will be deprecated. 492 * <p> 493 * flush() is preferred as it matches the JPA flush() method. 494 * </p> 495 */ 496 void flushBatch() throws PersistenceException; 497 498 /** 499 * Return the underlying Connection object. 500 * <p> 501 * Useful where a Developer wishes to use the JDBC API directly. Note that the 502 * commit() rollback() and end() methods on the Transaction should still be 503 * used. Calling these methods on the Connection would be a big no no unless 504 * you know what you are doing. 505 * </p> 506 * <p> 507 * Examples of when a developer may wish to use the connection directly are: 508 * Savepoints, advanced CLOB BLOB use and advanced stored procedure calls. 509 * </p> 510 */ 511 Connection getConnection(); 512 513 /** 514 * Add table modification information to the TransactionEvent. 515 * <p> 516 * Use this in conjunction with getConnection() and raw JDBC. 517 * </p> 518 * <p> 519 * This effectively informs Ebean of the data that has been changed by the 520 * transaction and this information is normally automatically handled by Ebean 521 * when you save entity beans or use UpdateSql etc. 522 * </p> 523 * <p> 524 * If you use raw JDBC then you can use this method to inform Ebean for the 525 * tables that have been modified. Ebean uses this information to keep its 526 * caches in synch and maintain text indexes. 527 * </p> 528 */ 529 void addModification(String tableName, boolean inserts, boolean updates, boolean deletes); 530 531 /** 532 * Add an arbitrary user object to the transaction. The objects added have no 533 * impact on any internals of ebean and are solely meant as a convenient 534 * method push user information (although somewhat replaced by TransactionCallback). 535 */ 536 void putUserObject(String name, Object value); 537 538 /** 539 * Get an object added with {@link #putUserObject(String, Object)}. 540 */ 541 Object getUserObject(String name); 542}