在同一线程中使用两个 sqlalchemy 连接器时 mysql 连接丢失

gmo*_*oss 9 mysql sqlalchemy

用例和背景:

我想SELECT GET_LOCK针对固定副本使用,因此我的所有服务器都可以看到针对我的数据子集的相同锁,但将针对 mysql 的负载分配给多个副本,以便我的服务器可以在数据的不同子集上工作数据。因此我有mysql_connector_locksmysql_connector_data

其中每个connector对象都是 sqlalchemy 引擎和 sessionmaker 的包装器。他们每个人都有

def get_mysql_session(self, isolation_level=None):
    if not self.session_maker:
        self.session_maker = sessionmaker()
        self.session_maker.configure(bind=self.engine)
    session = self.session_maker()
    if isolation_level is not None:
        session.connection(execution_options={'isolation_level': isolation_level.value})
    try:
        yield session
        session.commit()
    except Exception:
        session.rollback()
        raise
    finally:
        session.close()
Run Code Online (Sandbox Code Playgroud)

现在,我有了我的代码

for data_subset_id in partitioned_data:
    with mysql_connector_locks.get_mysql_session() as session_locks:
        try:
            with get_lock(session_locks, data_subset_id):
                with mysql_connector_data.get_mysql_session(
                    isolation_level=IsolationLevel.READ_UNCOMMITTED
                ) as session_data:
                    data = get_data(session_data, data_subset_id)
                    process_data(data)
        except LockNotAcquired:
            continue
Run Code Online (Sandbox Code Playgroud)

其中get_lock遵循获取锁的标准方法。

出了什么问题:

每个服务器都会经历一次循环迭代,获取第二次迭代的锁,并在调用 期间MySQLdb._exceptions.OperationalError: (2013, 'Lost connection to MySQL server during query')出现查询错误。set transaction isolation levelmysql_connector_data.get_mysql_session

同样:它成功获取锁、获取数据子集、释放锁、获取下一个锁,然后第二次获取数据失败。

其他背景

以前,我对锁和数据使用相同的连接器。这已经工作了很多年,没有任何问题。我正在尝试分配 的负载get_data,并且需要保持所有服务器共用的锁。如果我无法让它工作,我将切换到在公共 Redis 服务器中持有锁,但如果可能的话,我宁愿不走这条路。

感谢您的任何见解!