Class Transaction

  • Direct Known Subclasses:
    DefaultTransaction

    public abstract class Transaction
    extends java.lang.Object
    The base class of all supported transaction types
    • Field Detail

      • CFG_ROLLBACK_ON_COMMIT_ERROR

        public static java.lang.String CFG_ROLLBACK_ON_COMMIT_ERROR
      • CFG_ENABLE_TX_CACHE

        public static final java.lang.String CFG_ENABLE_TX_CACHE
        See Also:
        Constant Field Values
      • captureInvalidationStackTraces

        public static boolean captureInvalidationStackTraces
      • lastStartTL

        public static final java.lang.ThreadLocal<java.lang.Long> lastStartTL
      • attachedObjects

        protected final java.util.ArrayList<java.lang.Object> attachedObjects
    • Constructor Detail

      • Transaction

        public Transaction()
    • Method Detail

      • unsetTransactionFactory

        protected static void unsetTransactionFactory()
      • printContextInfo

        public void printContextInfo()
      • getBeginTransactionStack

        public java.util.Queue<java.lang.Throwable> getBeginTransactionStack()
        Returns a stack frame for currents transaction begin(). For diagnostic purposes only.
      • current

        public static Transaction current()
        Returns the current transaction instance. Please note that creating nested transactions by calling begin() does not create new transaction instances. After finishing the (outermost) transaction via commit() or rollback() the instance is discarded. The next call to current() creates a new instance.
      • getCurrentIfExists

        protected static Transaction getCurrentIfExists()
      • isCurrent

        public boolean isCurrent()
      • getObjectID

        public long getObjectID()
        returns a unique id for this Transaction object. Note that this ID stays the same if you call begin(), commit() more than once on the same object
        Returns:
        the unique object ID
      • isRunning

        public final boolean isRunning()
        Tells if there is currently a active transaction. Once begin() has been called the transaction is considered to be active. After calling commit() or rollback() the transaction is no longer active. If nested transactions are started it returns true until commit() or rollback() has been called on the outermost transaction even if inner transactions have been ended via commit or rollback.
      • isNested

        public boolean isNested()
      • setRollbackOnly

        public final void setRollbackOnly()
        Marks this transaction as rollback only. If this transaction is nested all enclosing transactions are marked rollback-only too. Calling commit() afterwards will in fact roll back the transaction and throw a TransactionException to indicate that commit has not been successful (only outermost transaction - nested transactions do not throw a exception). Example:
         Transaction.current().begin();
         {
                Transaction.current().begin();
            {
                        Transaction.current().setRollbackOnly();
            }
                Transaction.current().commit(); // no exception here; no commit or rollback either
         }
         Transaction.current().commit(); // throws exception + does rollback
         
      • isRollbackOnly

        public boolean isRollbackOnly()
        Tells if this transaction has been marked as rollback-only. This happens by calling setRollbackOnly() or rollback() upon a nested transaction. See setRollbackOnly() for more details.
      • clearRollbackOnly

        protected void clearRollbackOnly()
      • isInCommitOrRollback

        public static boolean isInCommitOrRollback()
        Checks whether there is a transaction running in the current thread and this transaction is in commit or rollback phase (including invalidation phase). This phase includes the commit/rollback call to the database and the followed notification/invalidation. Note: Do not use this method in your business code. This is a hybris internal method.
        Returns:
        true in case transaction is in commit or rollback phase
        Since:
        3.1-u4
      • getOpenTransactionCount

        public int getOpenTransactionCount()
        Returns the number of transactions that are open for this thread, which is of course 0 if no transaction is running, 1 if a transaction is running, 2 if we have a nested transaction and so on.
        Returns:
        the number of open transactions for this thread
      • increaseOpenTransactionCount

        protected void increaseOpenTransactionCount()
      • decreaseOpenTransactionCount

        protected void decreaseOpenTransactionCount()
      • calculatedUserTAEnabled

        protected boolean calculatedUserTAEnabled​(Tenant t)
      • onNestedBeginError

        protected void onNestedBeginError​(java.lang.Exception e)
      • onOuterBeginError

        protected void onOuterBeginError​(java.lang.Exception e)
      • checkForOtherCurrentTxRunning

        protected void checkForOtherCurrentTxRunning()
      • beginOuter

        protected void beginOuter()
      • loadAfterSaveListenerRegistry

        protected void loadAfterSaveListenerRegistry()
      • bindConnection

        protected ConnectionImpl bindConnection​(Tenant tenant,
                                                boolean userTAEnabled)
      • logBeforeBegin

        protected void logBeforeBegin()
      • getConnectionToBind

        protected ConnectionImpl getConnectionToBind​(HybrisDataSource dataSource)
                                              throws java.sql.SQLException
        Throws:
        java.sql.SQLException
      • commitConnectionAndClearAndUnsetAsCurrent

        protected void commitConnectionAndClearAndUnsetAsCurrent()
      • checkBeforeCommit

        protected void checkBeforeCommit()
      • logBeforeCommit

        protected void logBeforeCommit()
      • toException

        public static <ET extends java.lang.Exception> ET toException​(java.lang.Throwable e,
                                                                      java.lang.Class<ET> businessExceptionClass)
        Utility method to help handling business exceptions coming from execute(TransactionBody) method.
      • clearTxBoundConnectionAndNotifyCommit

        protected void clearTxBoundConnectionAndNotifyCommit()
      • clearTxBoundConnectionAndNotifyRollback

        protected void clearTxBoundConnectionAndNotifyRollback()
      • clearTxBoundConnectionAndNotify

        protected void clearTxBoundConnectionAndNotify​(boolean isCommit)
      • unsetTxBoundConnection

        protected void unsetTxBoundConnection()
      • invalidateAndNotifyCommit

        public void invalidateAndNotifyCommit​(java.lang.Object[] key,
                                              int invalidationDepth,
                                              int invalidationType)
      • notifyCommit

        public void notifyCommit()
      • checkBeforeRollback

        protected void checkBeforeRollback()
      • logBeforeRollback

        protected void logBeforeRollback()
      • rollbackOuter

        protected void rollbackOuter()
      • rollbackConnection

        protected void rollbackConnection()
                                   throws java.sql.SQLException
        Throws:
        java.sql.SQLException
      • rollbackConnection

        protected void rollbackConnection​(ConnectionImpl con)
                                   throws java.sql.SQLException
        Throws:
        java.sql.SQLException
      • invalidateAndNotifyRollback

        public void invalidateAndNotifyRollback​(java.lang.Object[] key,
                                                int invalidationDepth,
                                                int invalidationType)
      • notifyRollback

        public void notifyRollback()
      • execute

        public java.lang.Object execute​(TransactionBody transactionBody)
                                 throws java.lang.Exception
        Executes given code inside the current transaction. If this transaction is not currently running it will be started and committed at the end of execution. Otherwise whether begin nor commit is called since the enclosing transaction will do that.

        In case an exception is raised and this method started the transaction itself it will rollback any changes. If no own transaction was started the exception is simply thrown to the calling code.

        Parameters:
        transactionBody - the code to execute within this transaction
        Returns:
        the object returned by the executed code
        Throws:
        java.lang.Exception - in case the executed code raised an exception
      • execute

        public java.lang.Object execute​(TransactionBody transactionBody,
                                        java.lang.Class<? extends java.lang.Exception>... permittedExceptions)
                                 throws java.lang.Exception
        Executes given code inside the current transaction. If this transaction is not currently running it will be started and committed at the end of execution. Otherwise whether begin nor commit is called since the enclosing transaction will do that.

        In case an exception is raised and this method started the transaction itself it will rollback any changes. If no own transaction was started the exception is simply thrown to the calling code.

        Parameters:
        transactionBody - the code to execute within this transaction
        permittedExceptions - a list of exception classes which are actually allowed to be thrown without the transaction being rolled back; may be null if no exceptions are allowed to do so
        Returns:
        the object returned by the executed code
        Throws:
        java.lang.Exception - in case the executed code raised an exception
      • finishExecute

        protected void finishExecute​(java.lang.Throwable thrown,
                                     TransactionBody body,
                                     java.lang.Class<? extends java.lang.Exception>... permittedExceptions)
                              throws java.lang.Exception
        Throws:
        java.lang.Exception
      • isExceptionIsPermitted

        protected boolean isExceptionIsPermitted​(java.lang.Throwable thrown,
                                                 java.lang.Class<? extends java.lang.Exception>... permittedExceptions)
      • getContextEntry

        public java.lang.Object getContextEntry​(java.lang.Object key)
      • setContextEntry

        public void setContextEntry​(java.lang.Object key,
                                    java.lang.Object value)
      • invalidate

        public void invalidate​(AbstractCacheUnit unit,
                               int invalidationType)
      • invalidate

        public void invalidate​(AbstractCacheUnit unit,
                               int invalidationType,
                               boolean sendImmediately)
      • invalidate

        public void invalidate​(java.lang.Object[] key,
                               int invalidationTopicDepth,
                               int invalidationType)
      • invalidateFromDirectPersistence

        public void invalidateFromDirectPersistence​(java.lang.Object[] key,
                                                    PK pk,
                                                    int invalidationType)
      • removeFromEntityMap

        protected void removeFromEntityMap​(PK pk)
      • invalidate

        public void invalidate​(java.lang.Object[] key,
                               int invalidationTopicDepth,
                               int invalidationType,
                               boolean sendImmediately)
      • addToDelayedRollbackLocalInvalidations

        public void addToDelayedRollbackLocalInvalidations​(java.lang.Object[] key,
                                                           int type,
                                                           int topicdepth)
      • activateCache

        public void activateCache​(boolean activate)
        activated the cache for the current transaction (thread). WARNING: if deactivating the cache be sure you reactivate it inside a finally{} clause to avoid slowdown of the system.
        Parameters:
        activate - true to activate, false to deactivate
        Since:
        2.0
      • isInvalidated

        public boolean isInvalidated​(java.lang.Object[] key)
        Returns:
        true if the given key will be invalidated by executeInvalidations()
      • enableDelayedStore

        public void enableDelayedStore​(boolean delay)
        the "delayed store" feature enables you to delay all item modifications until the end of the transaction. note that if you set this parameter it will be resetted after each commit/rollback to the global parameter "transaction.delayedstore" in your project|local.properties.
      • setRollbackOnCommitError

        public void setRollbackOnCommitError​(boolean rollback)
        If set to true any error happening during database commit will cause also a rollback on database level. Normally this is not necessary but should be considered in case database transactions are still open after commit.

        Also see configuration parameter 'transaction.rollbackOnCommitError' which allows to enable this globally.

      • isRollbackOnCommitError

        public boolean isRollbackOnCommitError()
      • isDelayedStoreEnabled

        public boolean isDelayedStoreEnabled()
        returns true if all entity modifications should be delayed until the end of the TX. If not used the enableDelayedStore() method, the result will be the preset given in the parameter "transaction.delayedstore" (or true if this has not been specified)
      • flushDelayedStore

        public void flushDelayedStore()
        All entity modification delayed within the current transaction will be made persistent right now. Please note that no changes will be written to database in case this transaction is already marked as rollback-only!
      • flushDelayedStore

        protected void flushDelayedStore​(EntityInstance entity)
      • executeOrDelayStore

        public void executeOrDelayStore​(EntityInstance entity)
      • addToDelayedRemoval

        public void addToDelayedRemoval​(EntityInstance entity)
      • enableUserTransactionForThread

        public static void enableUserTransactionForThread​(boolean enable)
        Enable or disable the user of UserTransactions for the current thread. If you globally want to enable/disable this feature, use the config parameter transaction.enable=true|false (can be found in the project.properties).
        Parameters:
        enable - true to enable, false to disable UserTransactions for the current thread
        Since:
        1.3.1
      • isUserTransactionEnabled

        public static boolean isUserTransactionEnabled()
        check the value set using the enableUserTransactionForThread(Boolean) method. Note that there may be more parameters that are checked internally if a UserTransaction should be started, eg. this method may return true, but the global configuration parameter "transaction.enable" is set to false. in this case no transaction is started.
        Returns:
        false, if the user transactions are disabled using the 'enableUserTransactionForThread(..)' method, true otherwise.
        Since:
        1.3.1
      • activateAsCurrentTransaction

        public void activateAsCurrentTransaction()
        Makes this transaction the new current transaction.
        Throws:
        java.lang.IllegalStateException - if there is still a current transaction set which is running.
        Since:
        2.10
      • assertNoCurrentTransactionRunning

        protected void assertNoCurrentTransactionRunning()
      • setAsCurrent

        protected void setAsCurrent()
      • registerEntityInstance

        public void registerEntityInstance​(EntityInstance instance)
      • getAttachedEntityInstance

        public EntityInstance getAttachedEntityInstance​(PK pk)
      • reloadEntityInstance

        public void reloadEntityInstance​(PK pk)
      • getTXBoundConnection

        public ConnectionImpl getTXBoundConnection()
        Inside a transaction this method returns the transaction bound database connection.
        Throws:
        java.lang.IllegalStateException - if called outside a transaction
      • setTransactionIsolationLevel

        public void setTransactionIsolationLevel​(int level)
        Allows to choose the transaction isolation level to be used for starting a new transaction. Please set before starting. Otherwise behavior is not defined (see Connection.setTransactionIsolation(int) for details)!

        Use as follows:

         Transaction tx = Transaction.current();
         tx.setTransactionIsolationLevel(Connection.TRANSACTION_READ_COMMITTED);
         tx.begin();
         // ... business code
         tx.commit();
         

        Also note that after commit or rolling back the isolation level setting is cleared - it has to be set for each transaction anew!

        Parameters:
        level - the level - see Connection for details
      • performCommitBeginEvery

        public static Transaction performCommitBeginEvery​(Transaction existingTransaction,
                                                          int ms)
        Helper method to commit a transaction after it's running over given amount of time.

        This method performs a commit on existing transaction and starts new one when elapsed transaction time exceeds given threshold. When new transaction is started, it is returned so that the caller can use it to do further transaction processing (e.g. commit()).

        Parameters:
        existingTransaction - existing transaction
        ms - transaction time threshold
        Returns:
        New transaction object if the elapsed transaction time is greater than the threshold. Existing transaction otherwise.
      • clearDelayedConstrains

        public void clearDelayedConstrains​(PK itemPK)
      • lock

        public void lock​(Item item)
                  throws java.lang.IllegalStateException
        Lock's an entity for update, performing a row-level lock on the database.

        Calls to lock can only be made between calls to begin() and commit() or rollback(). All locks that are acquired during a transaction are automatically released on calls to commit() or rollback(). If a lock is held by another transaction, this method will block until the lock can be acquired.

        Depending on a the DBMS, a lock on a single row may result in locking an entire page. Locks should not be acquired on long-running transactions unless absolutely necessary. Note, that on some DBMS's, such as HSQLDB, row-level locking is not supported and any attempt to perform a lock will throw an UnsupportedOperationException.

        Also note that it's crucial to use the correct isolation level for getting the correct result after locking a item. For instance if you expect that a attribute ma have been changed while waiting for that lock it may be a good idea to use Connection.TRANSACTION_READ_COMMITTED to allow reading these changed values!

        Parameters:
        item - The entity to lock
        Throws:
        java.lang.NullPointerException - If an null value is passed into the lock method or if no primary key has been assigned to the entity.
        java.lang.IllegalStateException - If an attempt is made to lock an entity outside the bounds of the transaction, or an attempt is made to lock an entity that does not exist in the database.
        java.lang.UnsupportedOperationException - If the database does not support SELECT FOR UPDATE
      • isTxCacheEnabled

        public boolean isTxCacheEnabled()
        Tells whether this (running) transaction is using a local cache for all lookups which cannot be backed by the global 2n level cache due to this transaction having invalidation recorded affecting the lookup.

        The default mode is true and has the config setting CFG_ENABLE_TX_CACHE.

        See Also:
        enableTxCache(boolean)
      • enableTxCache

        public void enableTxCache​(boolean enable)
        For a running transaction this method allow to define whether or not a local cache should be used.
        See Also:
        isTxCacheEnabled()
      • attach

        public void attach​(java.lang.Object objectToAttach)
      • dettach

        public boolean dettach​(java.lang.Object objectToAttach)
      • getAttached

        public <T> T getAttached​(java.lang.Class<T> classOfAttachedObject)