django 使用悲观锁解决时间竞争问题

0x01 起因

由于使用celery beat,restart的时候会立刻执行积压的task,出现了数据重复的问题。
当然解决的方法有很多中,还是研究了下数据锁的使用方法。

0x02 解决问题

mysql存在两种数据存储类型 InnoDB,MyIsam

查看所用数据类型

1
select table_name,`engine` from information_schema.tables where table_schema ='database name'

由于我采用的InnoDB,所以发生了点意外,数据一直不更新。

后来查到解决方案:
http://www.oschina.net/question/1264516_167312

如果采用了 InnoDB,mysql innodb 不支持 select … for update nowait
只能手动设置 session级的 innodb_lock_wait_timeout

1
2
3
4
...
with transaction.atomic():
Job.objects.select_for_update().filter(xxx=xxx)
...