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
_______________________________________________
jboss-user mailing list
[email protected]
https://lists.jboss.org/mailman/listinfo/jboss-user