【问题标题】:Using Non Serializable objects in Activiti BPMN在 Activiti BPMN 中使用非序列化对象
【发布时间】:2016-03-28 18:47:16
【问题描述】:

我想使用 Activiti BPMN 流程来完成一些数据库更新任务。我的流程如下。

开始事件-> 服务任务 1 -> 服务任务 2 -> 服务任务 3 -> 结束事件

在Service task 1的服务实现类中:我为MySQL数据库创建了一个java.sql.Connection。我需要将相同的 Connection 对象传递给 Service Task 2 和 Service Task 3。基本上,这两个类将使用相同的 Connection 对象对数据库进行一些插入。

我尝试如下(dbConn是包含java.sql.Connection类型dbConnection的类)

execution.setVariable("DBConn",dbConn); 

但它给出了一个异常,因为连接对象是不可序列化的。

"org.activiti.engine.ActivitiException: Couldn't serialize value" 

那么在进程的服务任务之间传递此类不可序列化变量的最佳方式是什么?或者有没有办法在一个地方为多个服务任务定义这样的通用对象,并在服务任务中使用它们(类似于流程的全局变量)

【问题讨论】:

  • 有什么特殊原因要传递相同的连接对象吗?
  • 我想为服务任务 2 和服务任务 3 中的插入任务使用相同的连接。数据库连接是使用 setAutoCommit(false) 创建的。所以在执行服务任务 3 之后我想提交事务
  • 如果 - 由于某种意外原因 - 服务器崩溃并且您必须重新启动它会发生什么?
  • 那将是一个问题。您能否让我知道使用 activiti 处理数据库事务的任何其他方式。基本上我想创建一系列数据库更新,如果所有事务都成功,则最后提交事务,否则回滚所有事务。

标签: serialization activiti


【解决方案1】:

您可以在 Java 中使用 Thradlocal 将连接对象传递给不同的服务任务。

例如,使用如下所示的基类并从中扩展每个服务任务。然后,您可以使用 get 方法设置 dbConnection 并在需要时使用。

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();
    }
}

注意:
这种方法假设所有服务任务都在同一个线程中执行,这个特定问题就是这种情况,但是一旦您包含一些用户任务/计时器(或任何异步逻辑),这不再是一个可行的解决方案!

【讨论】:

    【解决方案2】:

    首先,您应该知道,一旦根据this 创建连接实例,绝对没有办法对其进行序列化。

    原因是连接使用了网络资源(例如 TCP/IP 套接字),该资源使用机器上的网络堆栈,最终使用机器的硬件。

    这让你只有这个选择:

    • 设置一个为您存储连接实例的 bean,我们称它为 myConnectionRegistry,此 bean 的作用域应为单例并注入您的所有 Java 委托(服务任务实现)
    • 在第一个任务中,您创建连接,然后将其注册到 myConnectionRegistry 中,使用类似 connectionRegistry.register(conn, wfId) 的内容,这会将连接实例添加到私有映射中......
    • 在后续任务中,您使用从私有映射中获取连接对象的方法从同一个 bean 中检索任务,如果映射中没有注册连接对象,则抛出异常
    • 有一个在该异常上触发的边界事件,并执行任何必要的操作来确保数据完整性(例如,我在评论中描述的用例)
    • 在最后一个服务任务中,取消注册您的连接(您也应该关闭它)以防止内存泄漏
    • 确保在设计解决方案时考虑到数据库池...等!

    干杯!

    【讨论】:

    • 非常感谢清晰的描述性解释,它给了我很好的指导。由于我是 activiti 的新手,这将有很大帮助。我将查看 activiti 用户指南中的相关部分来实现这一点。如果可能的话,请让我知道任何好的参考文章,关于在 activiti 中使用 beans 的博客。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多