01-10-2008 06:45 AM
try {
UserTransaction transaction = transactionService.getNonPropagatingUserTransaction();
transaction.begin();
authenticationService.authenticate(LOGIN, PASSWORD.toCharArray());
NodeRef nodeRef = new NodeRef("workspace://SpacesStore/rubbish"); // invalid input
int status = alfrescoContext.getTransaction().getStatus(); // 0
nodeService.getProperty(nodeRef, ContentModel.PROP_CATEGORIES);
}
catch (Exception e)
{
int status = alfrescoContext.getTransaction().getStatus(); // (*)
}
transaction.commit();
10-08-2008 09:49 AM
The second thing is that you need to be 100% sure that the transactions are not leaked out of scope. There are three ways to do this.
1. Fix up the try-catch-finally behaviour
2. (Recommended) Use the RetryingTransactionHelper available from TransactionService. It doesn't leak transactions!
3. Switch on debug to detect any leaked transactions: log4j.logger.org.alfresco.util.transaction.SpringAwareUserTransaction.trace=DEBUG
In your case, the unclosed transaction is going back into the thread pool. The next operation that attempts to start a new transaction on that thread will generate the "already marked for rollback" exception. That's exactly right. The transaction is still open, you're asking to continue doing some work on the transaction but the transaction is guaranteed to rollback.
10-09-2008 04:18 AM
…
Regarding the three ways you mention: I understand that you recommend RetryingTransactionHelper and I am actually using it in our Web layer (which is done in Wicket). However, it seems to be against the normal way in which one would handle an update request: In my web app, I'd like to open a transaction at the beginning of the request, then the MVC code of the web app (scattered over many Wicket components) would make calls to the Alfresco NodeService API and finally a commit() call would save the changes. With RetryingTransactionHelper, however, I cannot (?) do this but am instead forced to collect all calls to the NodeService API in one method, which does not seem natural. Do you have any recommendation for a situation like this?
Thanks for your help,
Kaspar
Transaction txn = txnService.getUserTranscation(…);
try
{
txn.begin();
// Do stuff
txn.commit();
}
catch (Throwable e)
{
// Try a rollback. This doesn't always work if the txn is already marked for rollback. But who cares as long as it is rolled back!
try
{
txn.rollback();
}
catch (Throwable e)
{
// Just log, don't rethrow
}
// Rethrow original exception
throw e;
}
Now, naturally, the outer try-catch can be virtual or implemented by some other mechanism. But either commit OR rollback must be called and the rollback should be wrapped in a try-catch to absorb any exception (illegal state, etc) that might hide the underlying, original exception that triggered the rollback in the first place.
Tags
Find what you came for
We want to make your experience in Hyland Connect as valuable as possible, so we put together some helpful links.