At times, you may need to demarcate transactions in your code. Generally, you should use programmatic demarcation as little as possible, as it is error-prone and can interfere with the application server’s own transaction demarcation mechanisms. If you find it necessary to use programmatic demarcation, you must be very careful to ensure that your code handles any unexpected errors and conditions.
The Oracle Commerce Platform includes three classes that you can use to demarcate transactions in code:
atg.dtm.UserTransactionDemarcation
can be used by J2EE components and Nucleus components to perform basic transaction demarcation. This class accesses theUserTransaction
object to perform its operations.atg.dtm.TransactionDemarcation
can be used by Nucleus components to demarcate areas of code at a fine granularity. J2EE components cannot use this class, because it accesses theTransactionManager
object directly.atg.dtm.AutoCloseTransactionDemarcation
is a subclass ofatg.dtm.TransactionDemarcation
that implements thejava.lang.AutoCloseable
interface. This class automatically ends transactions that are invoked withintry
-with-resources statements.
Using the UserTransactionDemarcation Class
The following example illustrates how to use the UserTransactionDemarcation
class:
UserTransactionDemarcation td = new UserTransactionDemarcation (); try { try { td.begin (); ... do transactional work ... } finally { td.end (); } } catch (TransactionDemarcationException exc) { ... handle the exception ... }
There are a few things to note about using the UserTransactionDemarcation
class:
The
begin()
method implements theREQUIRED
transaction mode only. If there is no transaction in place, it creates a new one; but if a transaction is already in place, that transaction is used.If
begin()
creates a new transaction, theend()
method commits that transaction, unless it is marked for rollback only. In that case,end()
rolls it back. However, ifbegin()
does not create a transaction (because there is already a transaction in place),end()
does nothing.The code must ensure that
end()
is always called, typically by using afinally
block.begin()
andend()
can throw exceptions of classatg.dtm.TransactionDemarcationException
. The calling code should log or handle these exceptions.
Using the TransactionDemarcation Class
The following example illustrates using the TransactionDemarcation
class:
TransactionManager tm = ... TransactionDemarcation td = new TransactionDemarcation (); try { boolean success = false; try { td.begin (tm, TransactionDemarcation.REQUIRED); ... do transactional work ... } finally { td.end (!success); } } catch (TransactionDemarcationException exc) { ... handle the exception ... }
There are a few things to note about using the TransactionDemarcation
class:
The
begin()
method takes two arguments. The first argument is theTransactionManager
object. The second argument specifies one of the 6 transaction modes:REQUIRED
,REQUIRES_NEW
,SUPPORTS
,NOT_SUPPORTED
,MANDATORY
, orNEVER
. If the second argument is not supplied, it defaults toREQUIRED
.The code must ensure that the
end()
method is always called, typically by using afinally
block.The
begin()
andend()
methods can throw exceptions of classatg.dtm.TransactionDemarcationException
. The calling code should log or handle these exceptions.
The TransactionDemarcation
class takes care of both creating and ending transactions. For example, if the TransactionDemarcation
object is used with a REQUIRES_NEW
transaction mode, the end()
call commits or rolls back the transaction created by the begin()
call. The application is not expected to commit or rollback the transaction itself.
Using the AutoCloseTransactionDemarcation Class
AutoCloseTransactionDemarcation
is a subclass of TransactionDemarcation
that implements the java.lang.AutoCloseable
interface. AutoCloseTransactionDemarcation
automatically ends transactions that are invoked within try
-with-resources statements. It also adds a Boolean success
property to control whether the transaction is rolled back. This property is false
by default, and should be set to true
after all other code in the transaction has completed successfully. If the value of success
is still false
when the transaction is closed, end(true)
is called to roll back the transaction.
The following example illustrates using the AutoCloseTransactionDemarcation
class:
try (AutoCloseTransactionDemarcation td = new AutoCloseTransactionDemarcation(getTransactionManager(), TransactionDemarcation.REQUIRED)) { ... do transactional work ... td.setSuccess(true); }