[jboss-user] [JBoss jBPM] - Rollback of a process using JTA inside jBPM - help

mrudulam do-not-reply at jboss.com
Wed Feb 14 01:16:30 EST 2007


The situation I am breaking my head over is this - Assume there is a simple 3 node process. Each node has its own action handler. In the second action handler, I have an update to another database (other than the jbpm). In the 3rd action handler, there is an exception. I am trying to combine nodes 2 and 3 as part of one transaction. [I am **not** having code to leave the nodes withing action handler for testing purposes]

I am using a servlet/stand alone program to instantiate the process, and using the javax.transaction.UserTransaction.begin() and commit() to demarcate transaction as show below and  I am testing this out in WSAD.

The transaction is managed beautifully - commits to jbpm database and the external database works fine, if there is no exception. However, if there is an exception (in the third actionhandler), the rollback of hte jbpm process takes place only by one node. It does not seem to conform to the begin/commit demarcations. The other rollback is fine.

Can anyone tell me what is wrong with the code? Is there a wrong usage of save jbpmContext or close or anything else?

Thanks for all your help

package com.excercise.jbpm;
  | 
  | public class JBPMTestServlet extends HttpServlet implements Servlet {
  | 	private static JbpmConfiguration jbpmConfiguration =
  | 		JbpmConfiguration.getInstance();
  | 	private static final String USER_TRANSACTION_JNDI_NAME = "UserTransaction";
  | 	private static long pid = 0L;
  | 	private PrintWriter out = null;
  | 	private Context ctx = null;
  | 	private DataSource ds = null;
  | 	private UserTransaction utx= null;
  | 
  | 	public void doPost(HttpServletRequest req, HttpServletResponse resp)
  | 		throws ServletException, IOException {
  | 
  | 		resp.setContentType("text/html");
  | 		out = resp.getWriter();
  | 		ProcessInstance pInstance = null;
  | 		ProcessDefinition pmpd = null;
  | 		Token token = null;
  | 		try {
  | 			ctx = new InitialContext();
  | 		} catch (NamingException e) {
  | 			out.println("ERROR! Could not get Initial Context.");
  | 			out.println("<br>" + e.getMessage() + "<br><pre>");
  | 			e.printStackTrace(new PrintWriter(out));
  | 			out.println("</pre>");
  | 		}
  | 
  | 		try
  | 		{
  | 		 utx = (UserTransaction)
  | 		   ctx.lookup("java:comp/UserTransaction");
  | 		   System.out.println(utx);
  | 		}
  | 		catch (NamingException e) {
  | 				   out.println("ERROR! Could not get UserTransaction");
  | 				   out.println("<br>" + e.getMessage() + "<br><pre>");
  | 				   e.printStackTrace(new PrintWriter(out));
  | 				   out.println("</pre>");
  | 			   }
  | 		if (ctx != null) {
  | 			try {
  | 				ds = (DataSource) ctx.lookup("jdbc/jbpm");
  | 			} catch (NamingException e) {
  | 				out.println("ERROR! Could not find DSN.");
  | 				out.println("<br>" + e.getMessage() + "<br><pre>");
  | 				e.printStackTrace(new PrintWriter(out));
  | 				out.println("</pre>");
  | 			}  
  | 		} 
  | 		 
  | // **************************** Creating Process Instance and signalling to node1  **************************** //
  | 		JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
  | 		Connection conn = null;
  | 		try {
  | 			utx.begin();
  | 			conn = ds.getConnection();
  | 			conn.setAutoCommit(true);
  | 			jbpmContext.setConnection(conn);
  | 			pmpd =
  | 				jbpmContext.getGraphSession().findLatestProcessDefinition(
  | 					"JustNodesProcess");
  | 			pInstance = new ProcessInstance(pmpd);
  | 			pid = pInstance.getId();
  | 			token = pInstance.getRootToken();
  | 			out.println(
  | 				"Before signalling, the token is now at " + token.getNode() + "\n");
  | 			token.signal();
  | 			out.println(
  | 				"After signalling, the token is now at " + token.getNode() + "\n");
  | 			jbpmContext.save(pInstance);
  | 			out.println("After saving...\n");
  | 			utx.commit();
  | 		} catch (Exception e) {
  | 			e.printStackTrace();
  | 			out.println(e.getMessage());
  | 			try
  | 			{
  | 				utx.rollback();
  | 			}
  | 			catch (Exception ex)
  | 			{
  | 				ex.printStackTrace();
  | 			}
  | 		} finally {
  | 			jbpmContext.getSession().flush();
  | 			out.println("After flushin...\n");
  | 			jbpmContext.close();
  | 			out.println("After closing...\n");
  | 		
  | 		}
  | 		// **************************** Signalling to node2 and node3 **************************** //
  | 		/**
  | 		 * Note that node2 and node3 have been combined into one transaction.
  | 		 * Here we can give an exception in node3 and check if it rolls back to node2
  | 		 */
  | 		jbpmContext = jbpmConfiguration.createJbpmContext();
  | 		try {
  | 			utx.begin();
  | 			conn = ds.getConnection();
  | 			jbpmContext.setConnection(conn);
  | 			conn.setAutoCommit(true);
  | 			GraphSession graphSession = jbpmContext.getGraphSession();
  | 			pInstance = graphSession.loadProcessInstance(pid);
  | 			pInstance.signal();
  | 			pInstance.signal();
  | 			jbpmContext.save(pInstance);
  | 			utx.commit();
  | 		} catch (Exception e) {
  | 			e.printStackTrace();
  | 			out.println(e.getMessage());
  | 			try
  | 			{
  | 				utx.rollback();
  | 			}
  | 			catch (Exception ex)
  | 			{
  | 				ex.printStackTrace();
  | 			}
  | 			out.println("pInstance.hasEnded()" + pInstance.hasEnded());
  | 			List list = pInstance.findAllTokens();
  | 			out.println(
  | 				"pInstance tokens size is "
  | 					+ list.size()
  | 					+ " token is "
  | 					+ ((Token) list.get(0)).getNode());
  | 			return; 
  | 		} finally {
  | 			jbpmContext.getSession().flush();
  | 			jbpmContext.close();
  | 		}
  | 		// **************************** Signalling to End state **************************** //
  | 		jbpmContext = jbpmConfiguration.createJbpmContext();
  | 		try {
  | 			utx.begin();
  | 			conn = ds.getConnection();
  | 			conn.setAutoCommit(true);
  | 			jbpmContext.setConnection(conn);
  | 			GraphSession graphSession = jbpmContext.getGraphSession();
  | 			pInstance = graphSession.loadProcessInstance(pid);
  | 			pInstance.signal();
  | 			jbpmContext.save(pInstance);
  | 			utx.commit();
  | 		} catch (Exception e) {
  | 			e.printStackTrace();
  | 			out.println(e.getMessage());
  | 			try
  | 			{
  | 				utx.rollback();
  | 			}
  | 			catch (Exception ex)
  | 			{
  | 				ex.printStackTrace();
  | 			}
  | 			return;
  | 		} finally {
  | 			jbpmContext.getSession().flush();
  | 			jbpmContext.close();
  | 		}
  | 		return;
  | 	}
  | }
  | 

And the jbpm configuration is as shown below

<jbpm-configuration>
  | 
  |   <jbpm-context>
  |   	 <!--   <service name="persistence" factory="org.jbpm.persistence.db.DbPersistenceServiceFactory" /> -->
  |    <service name="persistence">
  |       <factory>
  |         <bean name="org.jbpm.persistence.db.DbPersistenceServiceFactory" class="org.jbpm.persistence.db.DbPersistenceServiceFactory">
  |           <field name="isTransactionEnabled"><false /></field>
  |         </bean>
  |       </factory>
  |     </service>
  |     <service name="message" factory="org.jbpm.msg.db.DbMessageServiceFactory" />
  |     <service name="scheduler" factory="org.jbpm.scheduler.db.DbSchedulerServiceFactory" />
  |     <service name="logging" factory="org.jbpm.logging.db.DbLoggingServiceFactory" />
  |     <service name="authentication" factory="org.jbpm.security.authentication.DefaultAuthenticationServiceFactory" />
  |   </jbpm-context>
  | 
  |   <!-- configuration resource files pointing to default configuration files in jbpm-{version}.jar -->
  |   <string name="resource.hibernate.cfg.xml" value="hibernate.cfg.xml" />
  |   <!-- <string name="resource.hibernate.properties" value="hibernate.properties" /> -->
  |   <string name="resource.business.calendar" value="org/jbpm/calendar/jbpm.business.calendar.properties" />
  |   <string name="resource.default.modules" value="org/jbpm/graph/def/jbpm.default.modules.properties" />
  |   <string name="resource.converter" value="org/jbpm/db/hibernate/jbpm.converter.properties" />
  |   <string name="resource.action.types" value="org/jbpm/graph/action/action.types.xml" />
  |   <string name="resource.node.types" value="org/jbpm/graph/node/node.types.xml" />
  |   <string name="resource.parsers" value="org/jbpm/jpdl/par/jbpm.parsers.xml" />
  |   <string name="resource.varmapping" value="org/jbpm/context/exe/jbpm.varmapping.xml" />
  | 
  |   <bean name="jbpm.task.instance.factory" class="org.jbpm.taskmgmt.impl.DefaultTaskInstanceFactoryImpl" singleton="true" />
  |   <bean name="jbpm.variable.resolver" class="org.jbpm.jpdl.el.impl.JbpmVariableResolver" singleton="true" />
  |   <long name="jbpm.msg.wait.timout" value="5000" singleton="true" />
  | 
  | </jbpm-configuration>
  | 


View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4016212#4016212

Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4016212



More information about the jboss-user mailing list