为啥在数据库队列中也会发生数据库脏写?
最后一条的金额,很明显是错了。
我这里的图片,是有做一下悲观锁的,但我刚开始是没有。也就是说出错的时候是没有用lockForUpdate
因为记录是在队列里面一条一条执行的,我觉得是可以不需要使用锁的,加了我反而才觉得多余
你们怎么理解这一现像
不懂
我说下我的理解哈 ,没加锁当然会有并发问题,很简单就可以想 我一个队列跑的时候还没到下面save()逻辑,
,加上你这里还有一个外部的网络IO,此时我再一个队列进来,读取的余额当然是一样的,而且你这个锁,如果数据库层面没有设置字段不能为负数,会出现并发扣款余额为负数的情况。再多说一句,这根本不叫脏写。
你可以看下队列任务是否存在多次投递
@Remember 一个队列还没跑完,他不应该是新的队列还没进来吗
当两个事务同时尝试去更新某一条数据记录时,就肯定会存在一个先一个后。而当事务A更新时,事务A还没提交,事务B就也过来进行更新,覆盖了事务A提交的更新数据,这就是脏写。
其实就是同一个队列,但发生了两个事务,这其实就是脏写。我觉得我说的没错
@深蓝色 引用你上面的话:
如果是 innodb,版本不是很老的话,默认的隔离级别都是可重复读,你可以自己查看,可重复读在更新的时候,读取的是当前读,不存在脏写。
@xh 两个进程同时执行一个队列倒是有可能,但是我是用supervsior去弄的,应该不会重复执行
看一下你的 supervsior 配置 numprocs 是否大于 1, 这类事务可以用一个独立的队列分类分发, 同类型只分发到这一个队列, 只开一个进程处理, 切勿多开.
你的问题出在于
@深蓝色 请教下为啥用supervsior 监听进程 就不会出现这个问题啊
@seth-shi 这是干货,不过目前确实是1
@dalang 如果用supervisor他应该是一个进程的,如果不用supervisor,有可能是把命令设置为背景执行,同时有多个命令在跑
@深蓝色 1. 附上你的
supervisor
配置截图, 2.supervisorctl status
附上最开始启动的截图, 有进程数量显示