thread-safety - 在 Huey 中使用线程管理共享资源
问题描述
我必须更新 peewee 数据库()中的许多行(每行增加一个值SqliteDatabase
)。有些对象可以不创建,所以我必须在使用它们之前使用默认值创建它们。我会使用 peewee 文档(原子更新)中的方法,但我不知道如何混合model.get_or_create()
和in [my_array]
.
所以我决定在事务中进行查询以在最后提交一次(我希望这样做)。
为什么我写堆栈溢出是因为我不知道如何db.atomic()
在 Huey 中使用线程(我用 4 个工人测试过),因为.atomic()
锁定了连接(peewee.OperationalError: database is locked
)。我试过使用@huey.lock_task
,但它不是我发现的问题的解决方案。
我班的代码:
class Article(Model):
name = CharField()
mention_number = IntegerField(default=0)
class Meta:
database = db
我的任务代码:
@huey.task(priority=30)
def update(names): # "names" is a list of strings
with db.atomic():
for name in names:
article, success = Article.get_or_create(name=name)
article.mention_number += 1
article.save()
解决方案
好吧,如果您使用的是最新版本的 Sqlite(3.24 或更高版本),您可以使用 Postgres 样式的 upsert 查询。Peewee 很好地支持这一点:http: //docs.peewee-orm.com/en/latest/peewee/api.html#Insert.on_conflict
要回答有关共享资源的另一个问题,从您的示例中不清楚您希望发生什么...... Sqlite 一次只允许一个写入事务。因此,如果您正在运行多个线程,那么在任何给定时间可能只有其中一个正在写入。
Peewee 将数据库连接存储在本地线程中,因此 Peewee 数据库可以安全地用于多线程应用程序中。
您没有提到为什么 huey lock_task 不起作用。
另一个建议是尝试将 WAL 模式与 Sqlite 一起使用,因为 WAL 模式允许多个读取器事务与单个写入器共存。
推荐阅读
- c# - 如果我使用参数重载,FromSqlRaw 和 FromSqlInterpolated 返回空集
- c# - 如何从 CollectionView 更改条目 GotFocus 上的标签颜色
- c# - 检查数组的顺序是否正确
- reactjs - Draft.js:文本编辑器从其他组件的状态填充值
- javascript - React Todo App 将类组件转换为功能组件时出现错误
- mysql - 如何在给定不同值的mysql中插入多个数据集(一次)?
- flutter - FirebaseCrashlytics,不会报告异常,但运行 .crash 会
- javascript - 我的桌子看起来很奇怪,无法弄清楚我在 javascript 上做错了什么
- javascript - React 和 Redux:在一个函数中调度所有操作
- kubernetes - Swagger 多个定义最佳实践