OSWorkflow (OpenSymphony Workflow) 是輕量級 Java 工作流引擎,2.7 版本需手動配置資料源與持久化映射。本文記錄在 Tomcat + MySQL 環境下,從資料源註冊到 osworkflow.xml 映射的完整落地步驟,解決官方文檔缺失導致的配置坑。
<Context path="/osworkflow_example"
docBase="osworkflow-2.7.0-example"
debug="99" reloadable="true" crossContext="true">
<Resource name="jdbc/DefaultDS"
auth="Container"
type="javax.sql.DataSource"/>
<ResourceParams name="jdbc/DefaultDS">
<parameter>
<name>factory</name>
<value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
</parameter>
<parameter><name>maxActive</name><value>100</value></parameter>
<parameter><name>maxIdle</name><value>30</value></parameter>
<parameter><name>maxWait</name><value>10000</value></parameter>
<parameter><name>username</name><value>root</value></parameter>
<parameter><name>password</name><value></value></parameter>
<parameter><name>driverClassName</name>
<value>org.gjt.mm.mysql.Driver</value></parameter>
<parameter><name>url</name>
<value>jdbc:mysql://localhost:3306/osworkflow?autoReconnect=true</value></parameter>
</ResourceParams>
</Context>
BasicDataSourceFactory 需 commons-dbcp.jar、commons-pool.jar 放入 Tomcat common/lib。org.gjt.mm.mysql.Driver (舊版),新版 (5.1+) 應用 com.mysql.jdbc.Driver 或 com.mysql.cj.jdbc.Driver (8.0+)。autoReconnect=false 配合 validationQuery。<osworkflow>
<persistence class="com.opensymphony.workflow.spi.jdbc.MySQLWorkflowStore">
<property key="datasource" value="jdbc/DefaultDS"/>
<property key="entry.sequence" value="select count(*) + 1 from os_wfentry"/>
<property key="entry.table" value="OS_WFENTRY"/>
<property key="entry.id" value="ID"/>
<property key="entry.name" value="NAME"/>
<property key="entry.state" value="STATE"/>
<!-- 步驟 ID 產生策略:MySQL 專用 UNION 子查詢 -->
<property key="step.sequence" value="select sum(c1) + 1 from (select 1 as tb, count(*) as c1 from os_currentstep union select 2 as tb, count(*) as c1 from os_historystep) as TabelaFinal"/>
<property key="step.sequence.increment" value="INSERT INTO OS_STEPIDS (ID) values (null)"/>
<property key="step.sequence.retrieve" value="SELECT max(ID) FROM OS_STEPIDS"/>
<property key="history.table" value="OS_HISTORYSTEP"/>
<property key="current.table" value="OS_CURRENTSTEP"/>
<property key="historyPrev.table" value="OS_HISTORYSTEP_PREV"/>
<property key="currentPrev.table" value="OS_CURRENTSTEP_PREV"/>
<!-- 其餘欄位映射省略,按實際表結構對齊 -->
</persistence>
</osworkflow>
OSWorkflow 預設不支援 MySQL AUTO_INCREMENT,需自定義 step.sequence:
OS_STEPIDS 表僅含 ID INT AUTO_INCREMENT PRIMARY KEY。increment 插入空行取得新 ID,retrieve 讀取 MAX(ID)。CREATE DATABASE osworkflow DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; USE osworkflow; CREATE TABLE OS_WFENTRY ( ID BIGINT NOT NULL PRIMARY KEY, NAME VARCHAR(255), STATE INT ) ENGINE=InnoDB; CREATE TABLE OS_CURRENTSTEP ( ID BIGINT NOT NULL PRIMARY KEY, ENTRY_ID BIGINT, STEP_ID INT, ACTION_ID INT, OWNER VARCHAR(255), START_DATE DATETIME, FINISH_DATE DATETIME, DUE_DATE DATETIME, STATUS VARCHAR(50) ) ENGINE=InnoDB; CREATE TABLE OS_HISTORYSTEP LIKE OS_CURRENTSTEP; CREATE TABLE OS_CURRENTSTEP_PREV (ID BIGINT, PREVIOUS_ID BIGINT, PRIMARY KEY (ID, PREVIOUS_ID)) ENGINE=InnoDB; CREATE TABLE OS_HISTORYSTEP_PREV LIKE OS_CURRENTSTEP_PREV; CREATE TABLE OS_STEPIDS (ID BIGINT AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB;
| 現象 | 原因 | 對策 |
|---|---|---|
啟動報 NameNotFoundException: jdbc/DefaultDS | Resource 名稱與 osworkflow.xml 的 datasource 不一致 | 統一為 jdbc/DefaultDS |
Communications link failure | MySQL wait_timeout 導致連線失效 | 換用 HikariCP,設定 idleTimeout、maxLifetime |
流程啟動報 Duplicate entry | step.sequence.increment 並發衝突 | 改用 REPLACE INTO 或資料庫序列 |
@Bean DataSource 替代 Tomcat 全域 JNDI,便於單元測試與雲原生部署。