JBPM+spring 排错经历

10个小时!被一个问题困扰!

问题描述:



用户执行一个任务的时候,JBPM没有把任务执行的结果持久化的数据库中。即没有任何的update或insert语句产生。而我所看的实例中,(实例没有spring),同样的代码却执行了持久化工作。通过观察流程的输出,已经可以看到成功的执行到了下一个流程节点,但是因为没有持久化,所以流程的信息没有被保存。



以下是java代码:
[quote]

jbpmTemplate.execute(new JbpmCallback(){



public Object doInJbpm(JbpmContext context) throws JbpmException {

TaskInstance instance = context.getTaskInstance(tid);

System.out.println("----------------"+instance.getName());

if("ok".equals(result))

{

instance.end();


}

if("no".equals(result))

{

instance.end("部门审批驳回");

}

return null;

}


});

[/quote]


因为使用了spring-jbpm-module,此处使用了它提供的jbpmTemplate



我开始跟踪源代码,在instance.end初设置断点。



TaskInstance类 执行end方法:核心代码:

if (transition==null) {

log.debug("completion of task '"+task.getName()+"' results in taking the default transition");

token.signal();

} else {

log.debug("completion of task '"+task.getName()+"' results in taking transition '"+transition+"'");

token.signal(transition);

}




然后进入Token类的signal方法

核心代码: node.leave(executionContext, transition);

进入Node类的leave方法:

核心代码:transition.take(executionContext);

进入Transition类的take方法:将执行环境传入方法中

核心代码:to.enter(executionContext);

再次进入Node类 这已经是下一个节点了。至此,已经完成了从一个节点进入另一个节点的过程调度。

没有发现任何的持久化代码!

究竟持久化代码在什么地方呐?

我突然想到,我使用的是JbpmTemplate类,调用它的doInJbpm方法,是一个回调方法,我于是又找到doInJbpm方法的源码:


public Object execute(final JbpmCallback callback) {

final JbpmContext context = getContext();



try {

// use the hibernateTemplate is present and if needed

if (hibernateTemplate != null && hasPersistenceService) {



// use hibernate template

return hibernateTemplate.execute(new HibernateCallback() {

/**

* @see org.springframework.orm.hibernate3.HibernateCallback#doInHibernate(org.hibernate.Session)

*/

public Object doInHibernate(Session session) throws HibernateException, SQLException {

// inject the session in the context

context.setSession(session);

return callback.doInJbpm(context);

}

});

}



// plain callback invocation (no template w/ persistence)

return callback.doInJbpm(context);



}

catch (JbpmException ex) {

throw convertJbpmException(ex);

}

finally {

releaseContext(context);

}



}


可以看到,它在执行完你实现的doInJbpm方法后在finally体中有个releaseContext方法,

从名字可以看出,该方法是释放jbpm上下文信息的。

看它的源码:

只有一句:jbpmContext.close();

再往里找:核心代码:


if (services!=null) {

try {

autoSave();

} finally {

services.close();

}

}




我看到了autoSave()方法。

我就开始找autoSave的源码:



if (autoSaveProcessInstances!=null) {

Iterator iter = autoSaveProcessInstances.iterator();

while (iter.hasNext()) {

ProcessInstance processInstance = (ProcessInstance) iter.next();

save(processInstance);

iter.remove();

}

}




我又执行了一次业务,发现执行到这儿的时候autoSaveProcessInstances是null,结果就没有执行下面的代码,整个执行也就结束了。

但是我在跟踪例子的时候发现它这儿的autoSaveProcessInstances也是null。

那是哪句呐?

又看了jbpmContext.close();源码:发现又有个finally块:

services.close();

继续找它的源码:

里面最核心的代码也只有一句: service.close();

service是个什么东东呐?是个接口,看它的实现:

通过断点跟踪,这儿的实现是:DbPersistenceService 这个也是我们在jbpm.cfg.xml中配置的。

看它对service.close的实现:



核心持久化代码:

Exception commitException = commit(); 这是在跟踪示例的时候发现是这一句完成的持久化工作。

从感觉上,似乎是异常后完成的事务提交...

而执行这一句的必要条件是:

if (! isRollbackOnly()) {....}

而我在跟踪我的代码的时候,发现这儿的if(...)内是false。。。这个isRollbackOnly是哪儿设置的呐?什么时候设置的 呐?我突然想起我对我的那个purchaseApplyService配置了spring的事务,于是我就去掉了事务配置。执行,结果还是一样。

我再次找了这个isRollbackOnly方法 。核心代码:return txService.isRollbackOnly();

这应该是个事务配置。但是在哪儿设置的rollbackOnly呐?我找到了TxService类。然后找到它的setRollbackOnly方法,使用eclipse找调用它的地方,发现:在JbpmContext类中有方法:


/**

* mark this transaction for rollback only in the persistence service.

* The {@link #close()} operation will then perform a rollback.

*/

public void setRollbackOnly() {

TxService txService = (services!=null ? services.getTxService() : null);

if (txService!=null) {

txService.setRollbackOnly();

} else {

throw new JbpmException("no transaction service configured");

}

}



于是我想,是不是我在使用springTemplate的方法时候,它给我提供的jbpmContext有问题呐?但是究竟是杂回事,我还是没有找到答案,但是找到个临时的解决办法,就是不使用jbpmContext,并且把JbpmConfiguration注入到我的PurchaseApplyFlowService类里。现在我的代码是:


JbpmContext jbpmContext=jbpmConfiguration.getCurrentJbpmContext();

if(jbpmContext==null)

{

jbpmContext=jbpmConfiguration.createJbpmContext();

}


TaskInstance ti=jbpmContext.getTaskInstance(Long.parseLong(taskId));

if("ok".equals(result))

{

ti.end();

}

if("no".equals(result))

{

ti.end("部门经理驳回");

}

jbpmContext.close();



执行,发现成功执行了持久化工作。。。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值