deprecate UserTransaction
The name of this interface is psychotic. It has nothing to do with users. It's certainly not a transaction involving users. Perhaps in the LSD fever-dream of a bearded Bay Area C++ programmer, you can have a TM which reaches out from the computer to run the two phase commit protocol across the database and the human operator of the system, but that's not possible in Java.
Worse, every method of this interface throws the checked type SystemException, which the actual clients of the interface can't possibly do anything useful with except throw new RuntimeException(uselessSystemException).
I therefore propose that we replace this thing with something else that doesn't suck. Something like this:
/**
* Declares methods allowing an application program to explicitly manage
* transaction boundaries.
*
* @since Jakarta Transactions 2.1
*/
public interface TransactionController {
/**
* Create a new transaction and associate it with the current thread.
*
* @exception IllegalStateException Thrown if the thread is already
* associated with a transaction and the {@link TransactionManager}
* implementation does not support nested transactions, or if the
* transaction manager encounters an unexpected error condition.
*
*/
void begin();
/**
* Complete the transaction associated with the current thread. When this
* method completes, the thread is no longer associated with a transaction.
*
* @exception SecurityException Thrown to indicate that the thread is
* not allowed to commit the transaction.
*
* @exception IllegalStateException Thrown if the current thread is not
* associated with a transaction, if the transaction has been rolled
* back rather than committed, if a heuristic decision was made and
* at least some relevant updates have been rolled back, or if the
* transaction manager encounters an unexpected error condition. In
* the case of a rollback or heuristic decision, the thrown
* {@link IllegalStateException} must contain a wrapped
* {@linkplain Throwable#getCause cause} of type
* {@link RollbackException}, {@link HeuristicMixedException}, or
* {@link HeuristicRollbackException}, as appropriate.
*
*/
void commit();
/**
* Roll back the transaction associated with the current thread. When this
* method completes, the thread is no longer associated with a transaction.
*
* @exception SecurityException Thrown to indicate that the thread is
* not allowed to roll back the transaction.
*
* @exception IllegalStateException Thrown if the current thread is
* not associated with a transaction or if the transaction manager
* encounters an unexpected error condition.
*
*/
void rollback();
/**
* Modify the transaction associated with the current thread such that
* the only possible outcome of the transaction is to roll back the
* transaction.
*
* @exception IllegalStateException Thrown if the current thread is
* not associated with a transaction or if the transaction manager
* encounters an unexpected error condition.
*
*/
void setRollbackOnly();
/**
* Determine whether the transaction associated with the current thread
* has been marked so that the only possible outcome of the transaction
* is to roll back the transaction.
*
* @return {@code true} if the current transaction has been marked for
* rollback, or {@code false} otherwise.
*/
boolean isRollbackOnly();
/**
* Obtain the status of the transaction associated with the current thread.
*
* @return The transaction status. If no transaction is associated with
* the current thread, this method returns the Status.NoTransaction
* value.
*
* @exception IllegalStateException Thrown if the transaction manager
* encounters an unexpected error condition.
*
*/
int getStatus();
/**
* Modify the timeout value that is associated with transactions started
* by the current thread with the {@link #begin} method.
*
* <p> If an application has not called this method, the transaction
* service uses some default value for the transaction timeout.
*
* @param seconds The value of the timeout in seconds. If the value is zero,
* the transaction service restores the default value. If the value
* is negative a SystemException is thrown.
*
* @exception IllegalStateException Thrown if the transaction manager
* encounters an unexpected error condition.
*
*/
void setTimeout(int seconds);
/**
* The timeout value that is associated with transactions started by
* the current thread with the {@link #begin} method.
*
* <p> If an application has not called this method, the transaction
* service uses some default value for the transaction timeout.
*
* @return The timeout in seconds
*
* @exception IllegalStateException Thrown if the transaction manager
* encounters an unexpected error condition.
*
*/
int getTimeout();
/**
* Run the given {@linkplain Runnable operation} in a transaction.
* If there is no active transaction associated with the current
* thread, {@linkplain #begin} a new transaction before running
* the operation. If the operation completes without throwing an
* exception, {@linkplain #commit} the transaction. If the
* operation does throw an exception, {@linkplain #rollback} the
* transaction and rethrow the exception. Otherwise, if there is
* already an active transaction associated with the current
* thread, simply call the operation.
*
* @param work Some work to be performed in a transaction
*
* @exception IllegalStateException Thrown if the current
* {@linkplain #getStatus status} is anything other than
* {@link Status#STATUS_ACTIVE STATUS_ACTIVE} or
* {@link Status#STATUS_MARKED_ROLLBACK STATUS_MARKED_ROLLBACK}
* or if committing the transaction fails.
*/
void runInTransaction(Runnable work);
/**
* Call the given {@linkplain Supplier supplier} in a transaction.
* If there is no active transaction associated with the current
* thread, {@linkplain #begin} a new transaction before running
* the operation. If the operation completes without throwing an
* exception, {@linkplain #commit} the transaction and return the
* value produced by the supplier. If the operation does throw an
* exception, {@linkplain #rollback} the transaction and rethrow
* the exception. Otherwise, if there is already an active
* transaction associated with the current thread, simply call the
* supplier and return the value it produces.
*
* @param work A supplier to be called in a transaction
* @return The value returned by the given supplier
* @param <R> The type of the value returned by the supplier
*
* @exception IllegalStateException Thrown if the current
* {@linkplain #getStatus status} is anything other than
* {@link Status#STATUS_ACTIVE STATUS_ACTIVE} or
* {@link Status#STATUS_MARKED_ROLLBACK STATUS_MARKED_ROLLBACK}
* or if committing the transaction fails.
*/
<R> R callInTransaction(Supplier<R> work);
}
Of course, I would also like getStatus() to return an enumerated type as proposed in #225.