Committing and backing out units of work

When you update IBM® Product Master entities, such as items and user-defined logs, you can group a batch of updates together into a single transaction.

About this task

Unlike the Script API, which uses a transaction by default, each data update in the Java™ API is completed in non-transactional mode unless otherwise specified. Therefore, that single update (for example, adding to a category or deleting an attribute) is auto-committed as soon as the command is entered.

To group a number of updates together, you must explicitly open a transaction. The updates are not completed until the transaction is committed, and if the transaction is rolled back, the updates are abandoned.

You can also complete a partial rollback within a transaction through savepoints. You set a savepoint to capture the state of a transaction at a particular point in time, and as long as the transaction is active you can roll back to the savepoint and restore the transaction to the saved state. If you roll back to a savepoint, you can commit the transaction, thus making permanent all the updates made up to the savepoint, or you can make further updates within the transaction and commit those updates as well.

Procedure

Use the following example:
Option Description
Using a transaction block in the Java API The following sample code demonstrates how to use a transaction block.
pimContext.startTransaction();
try 
{
   // perform updates here
   // ...
   pimContext.commit(); 
// commit transaction
}
catch (Exception e)
{
   pimContext.rollback(); 
// an error occurred, rollback changes
}
Safely starting a transaction
Important: Do not start a transaction if you are already in one.
To improve code maintainability and error handling, you cannot start a transaction if you are already in one. You must explicitly deal with the exception or prevent it from occurring. You can handle your startTransaction() call safe in either of the way:
  • Option 1: Handle the exception.
    {
       pimContext.startTransaction();
    }
    catch (PIMAlreadyInTransactionException e)
    {
       // At this point you could:
       // - throw an error to give up
       // - continue to join the current transaction
       // - pimContext.rollback() to rollback existing transaction, then call startTransaction() again
       // - pimContext.commit() to commit existing transaction, then call startTransaction() again
    }
  • Option 2: Make the exception impossible.
    if (!pimContext.inTransaction())
    {
       pimContext.startTransaction();
    }
    else
    {
       // At this point you could:
       // - throw an error to give up
       // - continue to join the current transaction
       // - pimContext.rollback() to rollback existing transaction, then call startTransaction() again
       // - pimContext.commit() to commit existing transaction, then call startTransaction() again
    }
    
Using a savepoint to perform a partial rollback The following code demonstrates the basic use of a savepoint. The idea is that you want to perform updates C and D atomically but even if either update fails you still want to commit updates A and B.
pimContext.startTransaction();
try
{
    // perform update A
    // perform update B
    String name = pimContext.setSavepoint();
    try
    {
        // perform update C
        // perform update D
    }
    catch (Exception e)
    {
        pimContext.rollbackToSavepoint(name);
    }
    pimContext.commit();
    // commits the update of A and B. If C and D were
    // both updated without exception then also commits those.
    // Otherwise, updates to both C and D are not committed.
}
catch (Exception e)
{
    pimContext.rollback();
    // an error occurred, rollback all changes
}