首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >序列化访问上的SQLAlchemy / MySQL死锁

问序列化访问上的SQLAlchemy / MySQL死锁
EN

Stack Overflow用户
提问于 2016-08-28 11:24:33
回答 1查看 5K关注 0票数 5

与sqlalchemy一起使用的InnoDB表中的死锁有一个很大的问题。

sqlalchemy.exc.InternalError:(mysql.connector.errors.InternalError) 1213 (40001):尝试锁定时发现死锁;尝试重新启动事务。

我已经序列化了访问,但仍然会出现死锁错误。

此代码在每个函数中的第一个调用时执行。每个线程和进程都应该在这里等待,直到它获得锁。它简化了,因为选择器被移除。

代码语言:javascript
复制
    # The work with the index -1 always exists.
    f = s.query(WorkerInProgress).with_for_update().filter(
        WorkerInProgress.offset == -1).first()

我已经将我的代码压缩到了一个最小的状态。我目前只对方法next_slice运行并发调用。会话处理、回滚处理和死锁处理在外部处理。

即使所有的访问都是序列化的,我也会遇到死锁。我也尝试过在偏移量== -1实体中增加一个重试计数器。

代码语言:javascript
复制
def next_slice(self, s, processgroup_id, itemcount):
    f = s.query(WorkerInProgress).with_for_update().filter(
        WorkerInProgress.offset == -1).first()

    #Take first matching object if available / Maybe some workers failed
    item = s.query(WorkerInProgress).with_for_update().filter(
        WorkerInProgress.processgroup_id != processgroup_id,
        WorkerInProgress.processgroup_id != 'finished',
        WorkerInProgress.processgroup_id != 'finished!locked',
        WorkerInProgress.offset != -1
        ).order_by(WorkerInProgress.offset.asc()).limit(1).first()

    # *****
    # Some code is missing here. as it's not executed in my testcase

    # Fetch the latest item and add a new one 
    item = s.query(WorkerInProgress).with_for_update().order_by(
        WorkerInProgress.offset.desc()).limit(1).first()     

    new = WorkerInProgress()
    new.offset = item.offset + item.count
    new.count = itemcount
    new.maxtries = 3
    new.processgroup_id = processgroup_id
    s.add(new)
    s.commit()
    return new.offset, new.count

我不明白为什么会出现死锁。

通过在一个查询中获取所有项,我减少了死锁,但仍然会出现死锁。也许有人能帮我。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-08-30 15:30:37

最后我解决了我的问题。所有这些都在文档中,但我必须先理解它。

如果事务由于死锁而失败,请随时准备重新发出。死锁并不危险。再试一次。 来源:http://dev.mysql.com/doc/refman/5.7/en/innodb-deadlocks-handling.html

我改变了这个部分的结构,解决了我的问题。我仍然有很多死锁,但它们几乎出现在短时间运行的方法中。我已经把我的工人桌子分成了一个锁定部分和一个非锁定部分。锁定部分上的操作现在非常短,在get_slice、finish_slice和fail_slice操作期间没有处理任何数据。

具有数据处理的事务部分现在处于非锁定部分,并且没有对表行的并发访问。结果存储在finish_slice和fail_slice中,存储在锁定表中。

最后,我也找到了一个关于堆栈溢出的很好的描述。在确定正确的搜索词之后。https://stackoverflow.com/a/2596101/5532934

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39190752

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档