As we transition to the new Hyland Community, some post links may be temporarily disrupted as we finalize redirects. We apologize for the inconvenience and are working to resolve this as quickly as possible. Details.
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();
grep AlfrescoRuntimeException `find HEAD -name '*xml'`
An error occurred in one of the dashlets. * Failed to get to do tasks: javax.transaction.RollbackException: The transaction has already been marked for rollback * Failed to get pooled tasks: javax.transaction.RollbackException: The transaction has already been marked for rollback * Failed to get all active tasks: javax.transaction.RollbackException: The transaction has already been marked for rollback
package org.alfresco.web.action.evaluator; import javax.faces.context.FacesContext; import org.alfresco.web.bean.repository.Node; import org.alfresco.web.action.ActionEvaluator; import org.alfresco.model.ContentModel; import org.alfresco.service.cmr.dictionary.DictionaryService; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.security.AuthenticationService; import org.alfresco.service.namespace.QName; import org.alfresco.service.transaction.TransactionService; import org.alfresco.web.bean.ml.MultilingualUtils; import javax.faces.context.FacesContext; import javax.transaction.UserTransaction; import org.alfresco.web.app.servlet.FacesHelper; public class CutNodeEvaluator extends BaseActionEvaluator { public boolean evaluate(Node node) { // BEGIN for debugging only FacesContext fc = FacesContext.getCurrentInstance(); NodeService nodeService = (NodeService) FacesHelper.getManagedBean(fc, "NodeService"); TransactionService transactionService = (TransactionService) FacesHelper.getManagedBean(fc, "TransactionService"); AuthenticationService authenticationService = (AuthenticationService) FacesHelper.getManagedBean(fc, "AuthenticationService"); try { UserTransaction transaction = null; try { //transaction = transactionService.getNonPropagatingUserTransaction(); // (**) //transaction.begin(); // (**) //authenticationService.authenticate("admin", "J8uqw82_".toCharArray()); // (**) NodeRef nodeRef = new NodeRef("workspace://SpacesStore/rubbish"); // invalid input //int status = transaction.getStatus(); // 0 // (**) //System.err.println(status); // (**) nodeService.getProperty(nodeRef, ContentModel.PROP_CATEGORIES); } catch (Exception e) { // int status = transaction.getStatus(); // (*) // (**) // System.err.println(status); // (**) } // transaction.commit(); // (**) } catch (Exception e) { } // END for debugging only // just some dummy return value return false; } }
Hi,I need some advice from a Spring transaction guru, it seems: I don't get the following to work 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(); …Regards,Kaspar
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 behaviour2. (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.
…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; }