遇到的问题
假设拿医院系统的药品部分举例, 药品表结构大概如下:

现在有多个地方可能会去操作药品的数量:
- 护士生成请领单 (减存库数量,加冻结数量),可能会涉及到一堆表,那么这些操作都会在一个事务里,在操作存库的时候会把操作的行自动锁定起来,等待事务结束才会释放
- 手工划价药品 (直接减库存数量) 同上,会操作很多表的数据,一样会锁操作的行
- 药房发药 (减冻结数量) 同上,会操作很多表的数据,修改请领单状态等等,一样会锁操作的行
- ......
因为在系统里可能某些药的使用频率是非常高的,比如一些生理盐水、葡萄糖之类的。那么就经常会遇到,护士在生成请领单事务还没完成,药房正在发的药中也含有这些药,这样互相等待直接就被 mysql 的死锁检测机制检测到。
想请问大家遇到这种问题一般会采用什么样的方案来解决?
自己想到的方法以及问题
- 大事务拆各个小事务,比如药房发药,新事务->首先修改请领单状态->提交。新事务->再去减存库->提交。但是这样如果在减存库的地方异常了,不就不会回滚到 请领单状态
- 使用同步,我们首先尝试在生成请领单的方法上加上同步,这样多个护士在同时生成请领单的时候的确是不会遇到问题了,但是生成请领单又可能和发药死锁。如果加到减库存的方法,那似乎没什么用?就算减存库同步执行了,但是上层事务还没跑完 也会遇到这问题吧?
- 使用队列,因为我们现在多项目同时运行,并且都可能去操作存库,所以考虑过使用队列,把所有操作存库都丢到队列去单线程执行。但是改动速度有点大。
不知大家是否还有其他比较好的解决方案
试过,但是预算了一下,病人得排队到马路上。