多线程对于编程人员都不陌生,好比咱们经常使用的数据库链接池、tomcat等。本博客主要说一下我在工做中对多线程的使用的思考。具体多线程的使用方法就不在这里向你们介绍了。java
我最近作的项目是供应链相关的项目,而对于项目中涉及的各类单据都须要传给另一套系统作帐(财务系统),好比:合同单据、采购单据、收货单据等,每类单据都会有工做流。数据库
流程是这样的 首先在系统建立单据,提交以后开始走审批流及各类通知,当审批流审批结束以后,触发同步财务系统。当咱们系统有单据发生变化时,若是单据已经审批经过,会将变化的内容推送给财务系统。 编程
那这会有什么问题呢?假如咱们如今在作一个发票冲销的功能,当用户在页面点击它以后,首先在咱们系统完成冲销逻辑,而后调用财务系统将单据同步给它。 tomcat
起初咱们是采用同步的方式调用财务系统的接口,调用财务系统的接口咱们方法又须要等待它返回给咱们操做状态(成功仍是失败),而对于有修改的业务方法咱们都会在方法上使用事务,这会致使咱们方法占用事务时间过长产生数据库行级锁冲突问题。多线程
当项目上线以后,常常收到用户反馈说项目出错,查看日志发现常常出现行级锁问题。为何会产生行级锁问题呢?
好比采购单来讲,采购单采用的是头行结构(主单和明细),采购单包含采购的数量,收货数量,在途数量等字段,而在收货时,也会操做收货单对应的采购单,若是在采购单和收货单同时操做同一采购单号的单据,而且操做字段都须要同步到财务系统,就会致使方法占用事务过长,更容易产生行级锁问题。异步
除了会产生上面所说的行级锁问题以外,其实还有另一个问题,就是分布式事务来保证数据一致性问题。分布式
采用多线程的方式,将咱们系统中全部须要同步的到财务系统的地方都改为异步的方式,由于系统有不少种类型的单据,好比说咱们系统有6种单据,那咱们就建立一个大小为6的线程池,每一个线程池配一个阻塞队列。每一个线程池和6种单据一一对应,这样就能够保证咱们不会开启太多线程而占用系统资源。
例如采购单修改以后,除了作在本系统中的保存以外,同步到财务系统的地方只须要将采购单的同步请求放入线程池中。
除了异步的方式以外,咱们还能够同步的方式发送给对方系统以后,对方系统当即返回,当对方系统执行完毕以后,回调咱们系统的接口,咱们系统再作成功以后的逻辑处理。ide
除了上面这种方式以外,就是还能够采用MQ的方式,将须要同步的单据发送到MQ里面,对方系统从MQ里面取单据,取出的不一样单据作不一样的业务区分。线程