我想将Activiti BPMN流程用于某些数据库更新任务。我的流程如下。
开始活动 - >服务任务1 - >服务任务2 - >服务任务3 - >结束事件
在服务任务1的服务实现类中:我为MySQL数据库创建了一个java.sql.Connection。我需要将相同的Connection对象传递给服务任务2和服务任务3.基本上这两个类将使用相同的Connection对象对数据库进行一些插入。
我尝试如下(dbConn是包含java.sql.Connection类型dbConnection的类)
execution.setVariable("DBConn",dbConn);
但由于连接对象不可序列化,因此它会出现异常。
"org.activiti.engine.ActivitiException: Couldn't serialize value"
那么在进程的服务任务之间传递这种非可序列化变量的最佳方法是什么?或者有没有办法在一个地方为多个服务任务定义这样的公共对象,并在服务任务中使用它们(像过程的全局变量那样)
答案 0 :(得分:2)
首先,您应该知道,根据here创建连接实例后,绝对无法对其进行序列化。
原因是连接使用网络资源(例如TCP / IP套接字),该资源使用计算机上的网络堆栈,最终使用计算机的硬件。
只留下这个选择:
myConnectionRegistry
,这个bean的范围应该是单例并注入所有的java委托(服务任务实现)myConnectionRegistry
的内容将其注册到connectionRegistry.register(conn, wfId)
,这会将连接实例添加到私有地图.... 干杯!
答案 1 :(得分:2)
您可以在Java中使用Thradlocal将连接对象传递给不同的服务任务。
例如,使用如下所示的Base类,并从中扩展每个服务任务。然后,您可以设置dbConnection并在需要时使用get方法。
public class BaseServiceTask
{
public static final ThreadLocal<Connection> localConnectionContext = new ThreadLocal<Connection>();
public static void initDBConnector(Connection dbConn)
{
localConnectionContext.set(dbConn);
}
public static Connection getDBConnector()
{
return localConnectionContext.get();
}
}
注意:
这种方法假设所有服务任务都在同一个线程中执行,这就是这个特定问题的情况,但是一旦你包含了一些用户任务/计时器(或任何异步逻辑),这就不再是一个可行的解决方案了!