【问题标题】:Why one thread can't not detect the changed value updated by the other thread? [duplicate]为什么一个线程无法检测到另一个线程更新的更改值? [复制]
【发布时间】:2019-09-14 08:25:30
【问题描述】:

我正在使用 SQLAlchemy、python 和多线程编写程序。

在我的设计中,线程 A 使用了一个 while True 循环。在每个循环中,它通过 SQLAlchemy 从数据库中获取查询的对象,然后检查对象的一个​​字段。如果满足条件,则中断while循环。数据库中记录的字段将由线程B更新。

我的线程-A 代码:

    engine = create_engine('postgresql://postgres:passw0rd@localhost:5432/mini_amazon')
    Session = sessionmaker(bind=engine, expire_on_commit=False)

    @contextmanager
    def session_scope():
        """
        Provide a transactional scope around a series of operations.
        """
        session = Session()
        try:
            yield session
            session.commit()
        except:
            session.rollback()
            raise
        finally:
            session.close()

    with session_scope() as session:
        while True:
            print('Waiting')
            order = session.query(models.Order).get(arrived_message.packageid)
            time.sleep(1)
            if order.status == 'packed':
                break

        order.status = 'loading'

结果发现数据库中的记录已经被线程B更新为线程A中while循环的break-condition值。但是,Thread-A 一直在 while 循环中等待并且没有中断。

有人可以提供一些见解吗?

谢谢!

【问题讨论】:

  • 事务被隔离。在一个线程中发生的事情(无论是否在另一个线程中)不会影响另一个线程(至少在提交之前)。
  • 在我的例子中,Thread-B 更新数据库并立即提交()。如果我查看数据库,值会改变
  • 但 Thread-A 持有并使用不受此影响的开放事务。

标签: python orm sqlalchemy


【解决方案1】:

这是由交易的孤立性质造成的

具有平均隔离度的事务将保持它迄今已加载的状态,并继续为您提供事务本地相同的状态,即使实际数据已更改 - 这在事务隔离中称为可重复读取用语。

How to disable SQLAlchemy caching?

【讨论】:

  • My Thread-B commit() 更新值后,还是你说的这种情况吗?
  • 线程B的事务完成,更新数据库。但是 Thread-A 的事务不是。 Thread-A 仍会读取旧值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-09
  • 1970-01-01
  • 2021-01-29
  • 2020-09-30
相关资源
最近更新 更多