【发布时间】:2016-01-24 18:39:06
【问题描述】:
我有一个脚本可以在数据库中查询“博客”,并且对于每个博客,启动一个线程来查询其 RSS 地址并检查新帖子并将它们记录在数据库中。最初,我使用最多两个并行线程运行此脚本(同时从至少两个博客的 rss 中检索信息),然后,我开始收到此“数据库锁定错误”,现在我将其减少为一个,我仍然收到此错误。
对于数据库连接和 ORM,我使用的是 peewee 2.7.4,如下所示:
from peewee import *
from playhouse.sqlite_ext import SqliteExtDatabase
db = SqliteExtDatabase(APP_DIR + '/ml.db')
class BaseModel(Model):
class Meta:
database = db
class Blog(BaseModel):
(...)
class Post(BaseModel):
(...)
所以,启动它的脚本:
def start():
global ACTIVE_THREADS, MAX_THREADS
blogs = Blog.select().where(Block.active=1)
for blog in blogs:
while ACTIVE_THREADS == MAX_THREADS:
print 'Max number of threads %d reached. zzzz' % MAX_THREADS
time.sleep(1)
blog.processing=1
blog.save()
ACTIVE_THREADS += 1
th = threading.Thread(target=process_blog, args=(blog,))
th.daemon = True
th.start()
def process_blog(blog):
globals ACTIVE_THREADS
get_new_posts_url_for_blog(blog) # here Post records are created with downloaded=0
posts = Post.select().where(Post.downloaded = 0)
for post in posts:
content = get_content_for_post(post.url)
post.content = content
post.downloaded = 1
post.save() #This is where the database locked error is thrown :(
ACTIVE_THREADS -= 1
当然,这是脚本的简化版本,但基本上就是这样,在“posts”的第一个循环中,我在 post.save() 上收到以下错误:
File "/home/thilux/virtual_envs/ptmla/local/lib/python2.7/site-packages/peewee.py", line 4573, in save
rows = self.update(**field_dict).where(self._pk_expr()).execute()
File "/home/thilux/virtual_envs/ptmla/local/lib/python2.7/site-packages/peewee.py", line 3013, in execute
return self.database.rows_affected(self._execute())
File "/home/thilux/virtual_envs/ptmla/local/lib/python2.7/site-packages/peewee.py", line 2555, in _execute
return self.database.execute_sql(sql, params, self.require_commit)
File "/home/thilux/virtual_envs/ptmla/local/lib/python2.7/site-packages/peewee.py", line 3366, in execute_sql
self.commit()
File "/home/thilux/virtual_envs/ptmla/local/lib/python2.7/site-packages/peewee.py", line 3212, in __exit__
reraise(new_type, new_type(*exc_args), traceback)
File "/home/thilux/virtual_envs/ptmla/local/lib/python2.7/site-packages/peewee.py", line 3359, in execute_sql
cursor.execute(sql, params or ())
OperationalError: database is locked
请记住,现在我使用 MAX_THREADS=1 运行,因此一次只处理一个博客。最困扰我的是,在第一次运行时,我会以 MAX_THREADS=2 运行它,它会一直运行下去,很好。这个错误是几天后才开始的,所以我不知道是否可能在博客选择上,在主线程上,事情被锁定了(也许选择是附加的,我必须以某种方式分离它们)。谁能帮我解决这个问题?这确实是一个小过程,我不想为另一个数据库引擎进行更改,而且我看到了性能优势,这对于在至少 2 个并行线程中运行也很重要。
非常感谢您的帮助。
谢谢你, TS
【问题讨论】:
-
好吧,最后我决定重新设计我的应用程序以使用 MySQL 数据库。
标签: python multithreading python-2.7 sqlite peewee