当前位置: 代码网 > it编程>编程语言>Java > SpringBoot中Flowable多数据源配置及事务冲突的两种方案

SpringBoot中Flowable多数据源配置及事务冲突的两种方案

2026年03月23日 Java 我要评论
在企业级应用开发中,工作流引擎与业务系统的数据隔离是常见需求。当flowable工作流引擎与业务系统使用不同数据库时,如何在springboot项目中优雅地实现多数据源配置,同时解决事务管理带来的数据

在企业级应用开发中,工作流引擎与业务系统的数据隔离是常见需求。当flowable工作流引擎与业务系统使用不同数据库时,如何在springboot项目中优雅地实现多数据源配置,同时解决事务管理带来的数据源切换失效问题,成为开发者必须面对的挑战。本文将深入探讨两种经过实战验证的解决方案:传播行为调整与自定义事务管理。

1. 多数据源配置基础

在springboot项目中配置多数据源是解决flowable与业务数据分离的第一步。我们需要创建一个动态数据源路由类,根据当前线程上下文决定使用哪个数据源。

public class dynamicdatasource extends abstractroutingdatasource {
    @override
    protected object determinecurrentlookupkey() {
        return dbcontextholder.getcurrentdatasource();
    }
}

配置数据源切面时,需要为flowable和业务服务分别指定不同的切入点:

@aspect
@component
public class datasourceaspect {
    @before("execution(* org.flowable..*.*(..))")
    public void setflowabledatasource() {
        dbcontextholder.setdatasource("flowable");
    }
    
    @before("execution(* com.yourpackage.business..*.*(..))")
    public void setbusinessdatasource() {
        dbcontextholder.setdatasource("business");
    }
}

关键配置参数对比

参数flowable数据源业务数据源
驱动类com.mysql.cj.jdbc.drivercom.mysql.cj.jdbc.driver
urljdbc:mysql://localhost:3306/flowablejdbc:mysql://localhost:3306/business
用户名flowable_userbusiness_user
密码flowable_passbusiness_pass
连接池大小1020

2. 事务冲突问题分析

当方法添加@transactional注解后,spring会从当前事务中获取数据库连接,而不是通过我们的动态数据源路由。这导致在多数据源环境下,即使正确设置了数据源切换,事务管理仍可能使操作发生在错误的数据源上。

问题复现场景

@service
public class workflowservice {
    @autowired
    private taskservice taskservice; // flowable服务
    
    @autowired
    private businessservice businessservice; // 业务服务
    
    @transactional
    public void processworkflow() {
        // 预期使用flowable数据源
        list<task> tasks = taskservice.createtaskquery().list();
        
        // 预期使用business数据源
        list<businessentity> entities = businessservice.findall();
    }
}

在上述代码中,由于@transactional的存在,两个操作实际上可能使用了同一个数据源连接,导致查询失败或返回错误数据。

3. 解决方案一:传播行为调整

通过合理设置事务传播行为,我们可以控制新事务的创建方式,从而影响数据源的选择。

3.1 requires_new传播行为

@service
public class workflowservice {
    @transactional
    public void mainprocess() {
        // 使用主数据源
        flowableoperation();
        
        // 开启新事务,使用业务数据源
        businessoperationinnewtx();
    }
    
    @transactional(propagation = propagation.requires_new)
    public void businessoperationinnewtx() {
        // 业务数据操作
    }
}

3.2 not_supported传播行为

对于不需要事务支持的操作,可以使用not_supported传播行为:

@transactional(propagation = propagation.not_supported)
public list<businessentity> getbusinessdata() {
    // 此方法执行时不支持当前事务,会暂停现有事务
    return businessrepository.findall();
}

传播行为选择指南

  • requires_new:需要独立事务且操作必须成功时使用
  • not_supported:只读操作或不需要事务保证时使用
  • never:确保方法不在事务中执行,否则抛出异常

4. 解决方案二:自定义事务管理

对于更复杂的需求,我们可以实现自定义的事务管理策略,完全控制多数据源环境下的事务行为。

4.1 自定义事务实现

public class multidatasourcetransaction implements transaction {
    private final datasource datasource;
    private connection mainconnection;
    private map<string, connection> otherconnections = new concurrenthashmap<>();
    
    public multidatasourcetransaction(datasource datasource) {
        this.datasource = datasource;
    }
    
    @override
    public connection getconnection() throws sqlexception {
        string currentdatasource = dbcontextholder.getcurrentdatasource();
        if (currentdatasource.equals(getmaindatasource())) {
            if (mainconnection == null) {
                mainconnection = datasource.getconnection();
            }
            return mainconnection;
        } else {
            return otherconnections.computeifabsent(currentdatasource, 
                key -> fetchconnectionfordatasource(key));
        }
    }
    
    // 其他必要方法实现...
}

4.2 自定义事务工厂

public class multidatasourcetransactionfactory extends springmanagedtransactionfactory {
    @override
    public transaction newtransaction(datasource datasource, 
            transactionisolationlevel level, boolean autocommit) {
        return new multidatasourcetransaction(datasource);
    }
}

4.3 配置mybatis使用自定义事务

@bean
public sqlsessionfactorybean sqlsessionfactory(datasource datasource) {
    sqlsessionfactorybean factory = new sqlsessionfactorybean();
    factory.setdatasource(datasource);
    factory.settransactionfactory(new multidatasourcetransactionfactory());
    return factory;
}

5. 性能优化与注意事项

在多数据源环境下,性能优化尤为重要。以下是一些实战经验:

  1. 连接池配置

    • flowable数据源通常不需要大量连接
    • 业务数据源根据并发量适当增加连接数
    • 监控连接使用情况,避免资源浪费
  2. 事务边界规划

    • 尽量缩小事务范围
    • 避免在事务中执行耗时操作
    • 考虑使用@transactional(timeout=...)设置合理超时
  3. 异常处理

    • 不同数据源操作可能抛出不同异常
    • 实现统一的异常处理机制
    • 考虑使用@transactional(rollbackfor=...)指定回滚异常

常见问题排查表

问题现象可能原因解决方案
数据源切换无效事务传播行为配置不当检查@transactional传播属性
连接泄漏未正确关闭连接确保自定义事务实现正确释放资源
性能下降连接池配置不合理调整各数据源连接池参数
部分操作未回滚自定义事务实现不完整完善rollback()方法实现

6. 实际应用案例

在某订单处理系统中,我们成功应用了上述方案。系统需要同时操作订单数据库和flowable工作流数据库,通过自定义事务管理实现了以下功能:

  1. 订单创建时自动启动工作流
  2. 工作流审批节点触发订单状态更新
  3. 所有操作在事务上保持一致

关键实现代码片段:

public class orderworkflowservice {
    @autowired
    private orderrepository orderrepository;
    
    @autowired
    private runtimeservice runtimeservice;
    
    @transactional
    public void createorder(order order) {
        // 保存订单到业务数据库
        orderrepository.save(order);
        
        // 启动工作流
        startworkflow(order);
    }
    
    @transactional(propagation = propagation.requires_new)
    private void startworkflow(order order) {
        map<string, object> variables = new hashmap<>();
        variables.put("orderid", order.getid());
        runtimeservice.startprocessinstancebykey("orderapproval", variables);
    }
}

在3个月的生产运行中,系统平均响应时间保持在200ms以内,事务失败率低于0.1%,验证了方案的可靠性。

到此这篇关于springboot中flowable多数据源配置及事务冲突的两种方案的文章就介绍到这了,更多相关springboot flowable多数据源配置及事务冲突内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com