# Activiti和业务库共用事务?继承MyBatis的JdbcTransaction,空壳化搞定

张开发
2026/4/15 9:11:43 15 分钟阅读

分享文章

# Activiti和业务库共用事务?继承MyBatis的JdbcTransaction,空壳化搞定
Activiti和业务库共用事务继承MyBatis的JdbcTransaction空壳化搞定非科班野生程序员深耕政务信息化20年。从VC到PB再到Java自研框架browise也打磨了十几年。最近整理框架代码发现不少有趣的决策写出来和大家聊聊。最后感谢豆包、智谱、OpenCode决策是我做的代码是我搓的文字是他们总结的。问题从哪来的做政务项目业务表和工作流引擎Activiti各管各的但实际运行时业务数据和流程实例必须在同一个事务里。比如一个审批提交操作更新业务表状态驱动Activiti流程往下走这两步要么一起成功要么一起回滚。但Activiti默认自己管连接MyBatis也自己管连接两个连接怎么绑到一起我的方案思路既然框架里已经有一套事务管理DBUtil.BeginTrans/DBUtil.EndTrans那让Activiti的MyBatis也用同一个连接就行了。怎么做继承JdbcTransaction把它的 commit/rollback/close 全部架空让统一事务管理器来管。代码// CustomJdbcTransaction.javapublicclassCustomJdbcTransactionextendsJdbcTransaction{privatestaticfinalLoglogLogFactory.getLog(CustomJdbcTransaction.class);publicCustomJdbcTransaction(Connectionconnection){super(connection);this.connectionconnection;if(connectionnull){try{DBUtil.BeginTrans(null,false);}catch(utilException e){e.printStackTrace();}AppContextcontextAppContextContainer.getAppContext();this.connectioncontext.getSeesion().getSession().getConnection();}}publicCustomJdbcTransaction(DataSourceds,TransactionIsolationLeveldesiredLevel,booleandesiredAutoCommit){super(ds,desiredLevel,desiredAutoCommit);}OverrideprotectedvoidopenConnection()throwsSQLException{if(connectionnull){try{DBUtil.BeginTrans(null,false);}catch(utilException e){e.printStackTrace();}AppContextcontextAppContextContainer.getAppContext();connectioncontext.getSeesion().getSession().getConnection();}log.debug({CustomJdbcTransaction } Openning JDBC Connectionconnection.hashCode()[]autoCommmit);if(level!null){connection.setTransactionIsolation(level.getLevel());}setDesiredAutoCommit(autoCommmit);}OverridepublicConnectiongetConnection(){try{if(connectionnull){try{DBUtil.BeginTrans(null,false);}catch(utilException e){e.printStackTrace();}AppContextcontextAppContextContainer.getAppContext();connectioncontext.getSeesion().getSession().getConnection();log.debug({CustomJdbcTransaction } closing JDBC Connectionconnection.hashCode());}returnconnection;}catch(Exceptione){System.out.println(获取链接失败e);returnnull;}}Overridepublicvoidclose()throwsSQLException{log.debug(关闭没有什么用,统一管理!);}Overridepublicvoidcommit()throwsSQLException{log.debug(提交没有什么用,统一管理!);}Overridepublicvoidrollback()throwsSQLException{log.debug(回滚没有什么用,统一管理!);}}关键点三个方法全部架空commit()、rollback()、close()里面什么都不做只打一行日志。为什么因为事务的生命周期交给外层的DBUtil.BeginTrans/DBUtil.EndTrans统一管理了这里不能自己提交或关闭。连接从哪来每次需要 Connection 的时候都从AppContextContainer里取当前请求上下文的 Session拿到的是同一个连接。Activiti 和业务操作用的是同一个 JDBC Connection自然就在同一个事务里了。空壳化的好处不侵入 Activiti 的源码不改 MyBatis 的核心逻辑。只需要在 Activiti 的配置里把这个CustomJdbcTransaction指定为事务工厂就行。为什么不用Spring的事务管理政务项目部署环境复杂有些老系统还在跑 WebLogic、ResinSpring的声明式事务在不同容器里行为不一致。自己管事务虽然土但可控。出了问题看日志就知道连接的hashCode是不是同一个一目了然。小结这个类的思路很简单你让我管事务我就管你不让我管我也不管。做一个空壳子套在 Activiti 的 MyBatis 外面让连接统一分配。整个类才117行但解决了政务项目里工作流和业务数据必须同事务的核心问题。觉得有用点个赞再走。有问题评论区见这个方案我们跑了8年没出过事务不一致的问题。标签#Java #MyBatis #Activiti #事务管理 #政务信息化 #自研框架

更多文章