cancel
Showing results for 
Search instead for 
Did you mean: 

Manage Transaction with Web Script

scoppola
Champ in-the-making
Champ in-the-making
Hi all,
i have the following issue:
How i can manage transaction in alfresco with Web Script?
I could image i have to implement a Java Web Script that uses embedded API to get transaction service and session.
Is this possible?

Thanks a lot.

Salvatore Coppola
5 REPLIES 5

scoppola
Champ in-the-making
Champ in-the-making
Hi again,
here is my solution to manage transaction with web script, i think it should be good, but It seems strange rivet logic doesn't implemented it in their API.
So i thought there's a problem i don't see.
Any comment ?
Other Solution ?

package com.accenture;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.Writer;

import javax.jcr.LoginException;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.SimpleCredentials;

import javax.transaction.HeuristicMixedException;
import javax.transaction.HeuristicRollbackException;
import javax.transaction.NotSupportedException;
import javax.transaction.RollbackException;
import javax.transaction.SystemException;
import javax.transaction.UserTransaction;

import org.alfresco.jcr.repository.RepositoryImpl;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.web.scripts.AbstractWebScript;
import org.alfresco.web.scripts.WebScriptRequest;
import org.alfresco.web.scripts.WebScriptResponse;

public class TransactionScript extends AbstractWebScript{
   public enum Action{
      COMMIT,
      COMMIT_TRANSACTION,
      ROLLBACK_TRANSACTION,
      BEGIN_TRANSACTION
   }
   
   private String user="";
   private String password="";
   private ServiceRegistry serviceRegistry = null;
   private UserTransaction userTransaction = null;   
   private RepositoryImpl repository = null;
   private Session session = null;
   private Action action = null;

   public void execute(WebScriptRequest req, WebScriptResponse res)
         throws IOException {
      setUser(req.getParameter("user"));
      setPassword(req.getParameter("password"));
      setAction(Action.valueOf(req.getParameter("action")));
      Writer pw = res.getWriter();
      
      Action currentAction = getAction();
      
      try{
         switch(currentAction){
            case COMMIT:{
               commit();
               pw.write(currentAction.name() + " effettuato.");
               break;
            }
            case COMMIT_TRANSACTION:{
               pw.write(currentAction.name() + " effettuato.");
               commitTransaction();
               break;
            }
            case ROLLBACK_TRANSACTION:{
               pw.write(currentAction.name() + " effettuato.");
               rollbackTransaction();
               break;
            }
            case BEGIN_TRANSACTION:{
               pw.write(currentAction.name() + " effettuato.");
               beginTransaction();
               break;
            }
         }
      } catch(LoginException e){
         pw = res.getWriter();
         pw.write("Autenticazione su Alfresco non riuscita. " + currentAction.name());   
         e.printStackTrace(new PrintWriter(pw));
      } catch (RepositoryException e) {
         pw = res.getWriter();
         pw.write("Autenticazione su Alfresco non riuscita. " + currentAction.name());
         e.printStackTrace(new PrintWriter(pw));
      } catch (SecurityException e) {
         pw = res.getWriter();
         pw.write("Autenticazione su Alfresco non riuscita. " + currentAction.name());
         e.printStackTrace(new PrintWriter(pw));
      } catch (IllegalStateException e) {
         pw = res.getWriter();
         pw.write("Autenticazione su Alfresco non riuscita. " + currentAction.name());
         e.printStackTrace(new PrintWriter(pw));
      } catch (RollbackException e) {
         pw = res.getWriter();
         pw.write("Autenticazione su Alfresco non riuscita. " + currentAction.name());
         e.printStackTrace(new PrintWriter(pw));
      } catch (HeuristicMixedException e) {
         pw = res.getWriter();
         pw.write("Autenticazione su Alfresco non riuscita. " + currentAction.name());
         e.printStackTrace(new PrintWriter(pw));
      } catch (HeuristicRollbackException e) {
         pw = res.getWriter();
         pw.write("Autenticazione su Alfresco non riuscita. " + currentAction.name());
         e.printStackTrace(new PrintWriter(pw));
      } catch (SystemException e) {
         pw = res.getWriter();
         pw.write("Autenticazione su Alfresco non riuscita. " + currentAction.name());
         e.printStackTrace(new PrintWriter(pw));
      } catch (NotSupportedException e) {
         pw = res.getWriter();
         pw.write("Autenticazione su Alfresco non riuscita. " + currentAction.name());
         e.printStackTrace(new PrintWriter(pw));
      }            

   }
   
   private void connect() throws LoginException, RepositoryException{
      session = repository.login(new SimpleCredentials(getUser(), getPassword().toCharArray()));
   }
   
   public ServiceRegistry getServiceRegistry() {
      return serviceRegistry;
   }

   public void setServiceRegistry(ServiceRegistry serviceRegistry) {
      this.serviceRegistry = serviceRegistry;
   }

   public void setRepository(RepositoryImpl repository) {
      this.repository = repository;
   }

   public RepositoryImpl getRepository() {
      return repository;
   }

   public String getPassword() {
      return password;
   }

   public void setPassword(String password) {
      this.password = password;
   }

   public String getUser() {
      return user;
   }

   public void setUser(String user) {
      this.user = user;
   }

   public Action getAction() {
      return action;
   }

   public void setAction(Action action) {
      this.action = action;
   }
   
   public Session getSession() {
      return session;
   }

   public void setSession(Session session) {
      this.session = session;
   }

   public void beginTransaction() throws NotSupportedException, SystemException{
      userTransaction = serviceRegistry.getTransactionService().getUserTransaction();
      userTransaction.begin();
   }
   
   public void commit() throws LoginException, RepositoryException{
      connect();
      session.save();
      close();
   }
   
   public void commitTransaction() throws LoginException, RepositoryException, SecurityException, IllegalStateException, RollbackException, HeuristicMixedException, HeuristicRollbackException, SystemException{
      connect();
      userTransaction.commit();
      session.save();
      close();

   }
   
   private void close() throws LoginException, RepositoryException{
      session.logout();
      
      serviceRegistry.getAuthenticationService().invalidateTicket(serviceRegistry.getAuthenticationService().getCurrentTicket());
      serviceRegistry.getAuthenticationService().clearCurrentSecurityContext();
         
      repository.deregisterSession();
   }
   
   public void rollbackTransaction() throws IllegalStateException, SecurityException, SystemException{

      userTransaction.rollback();

   }
}

scoppola
Champ in-the-making
Champ in-the-making
Hi all,
i realize tha bug in my code, everytime i call the WebScript i create a new session object that doesn't match the previous session i wanna use.
Any solution ?

openpj
Elite Collaborator
Elite Collaborator
You have to use the RetryingTransactionCallback of Spring and you can use an example in the Alfresco SDK in the FirstFoundationClient class:
http://svn.alfresco.com/repos/alfresco-open-mirror/alfresco/HEAD/root/projects/sdk/samples/FirstFoun...
Hope this helps.

mrogers
Star Contributor
Star Contributor
You can define the transactional semantics in the web script definition but In general each web script operates in its own transaction.

Your approach here worries me, in particular what is the connection between your transaction and Alfresco's transactions?
And even assuming that you can get your code to work it opens the possibility of long running or worse dangling uncommitted transactions.

I'd suggest you try to avoid this approach if possible.

scoppola
Champ in-the-making
Champ in-the-making
Thank you guys, i'm trying this approach because my problem is the following:
I have an application web client that uses alfresco's embedded API and I need to do remote calls to "Alfresco Remote API" removing local repository.
To do this i'm using RAAr, "rivet logic web API" , that unfortunately doesn't expose transaction and auditing service.

Unfortunately, project needs require to use a "parent" transaction which controls child-alfresco ones.

I try to write down a little example for a better understanding.

START PARENT TRANSACTION
   (SOME LOGIC)
—- ALFRESCO TR #1
—- ALFRESCO TR #2
—- ALFRESCO TR # N
          ……….
END PARENT TRANSACTION

I.e. If transaction #2 fails, we need to rollback the whole transaction…with actual solution I've used, I have TRANSCATION #1 commited.

Could you suggest a way to fix this scenario?

Thank you very much for your patience in advance.

Salvatore Coppola