【发布时间】:2017-12-26 06:18:05
【问题描述】:
我正在做一个 django 的项目,只是一个人的项目。
我用 celery 尝试了 django 的项目,并在 celery 中添加了两个任务。
一个任务,是关于蜘蛛通过请求写入,获取一些代理ip信息并通过django orm保存到mysql,即update_or_create(defaults={'ip':'','port':''},* *{'key':'value'})。我保持这个任务总是由一个工作人员通过 redis 锁控制数据。例如,一个工作运行任务,redis 锁获取,另一个工作尝试获取锁失败并且会不控制数据。
另外一个task,是一个spider,由tornado写,用来检查代理ip数据。此外,将由一名工作人员通过 redis 锁运行。龙卷风的蜘蛛也是单线程的。
这两个任务可以同时运行。
问题来了!
当我运行该项目几次后,大约几个小时后。我发现mysql中有一些数据是一样的。 ip,port和其他一些是一样的。
当代码运行到 update_or_create() 时出现错误:
get() 返回 2。
数据是怎么来的?在我看来,虽然最多两个线程会一起运行,但一个是使用 updata_or_create,一个是使用 .save() 。任务使用 save() 不会产生重复数据?而 update_or_create() 会检查数据get(),表示None表示数据库中没有这个ip和port这样的数据,但是,它有。
谁能给我解释一下原因?
【问题讨论】:
-
task需要代码 -
感谢您的回答。我正在将代码上传到github,在文件中:comm_tools..py 所有代码都在项目中。the project link
-
尝试获取
ProxyData动态,在put_ip_infor方法中移动data_need = ProxyData.objects.all(),如for each_data in ProxyData.objects.all() -
我正在尝试你所说的,结果可能是 30 或 60 分钟。如果我把
data_need = ProxyData.objects.all(0像for each_data in ProxyData.objects.all()一样放在put_ip_infor中,会有什么不同呢?在我眼里,我并没有什么不同,我的意思是,我不知道为什么要这样做?我认为错误的原因来自spider代理ips的部分,而不是检查部分? -
到目前为止,我已经得到了一些重复的数据。数据显示它是在不同时间创建的,在两个任务(获取 ip 数据并保存到 mysql)头和下面。其中一个尚未检查。
标签: mysql django django-models thread-safety