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}