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