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