在多个线程之间重用会话或连接时的注意事项

Snowflake 驱动程序使用有状态连接。在线程之间重用相同的会话或连接具有多个缺点。例如,初始化会话时,它以默认数据库、架构、角色和一组参数开始。连接启动和结束会话,从而在会话和连接之间建立一对一的关系。以下部分重点介绍跨并发线程重用连接时的常见影响。

跨多个线程重用会话或连接时的影响

驱动程序用户通常会创建多线程应用程序。您可以尝试在不同线程中重用会话或连接以节省一些开销,而不是为每个线程创建单独的会话和连接。请注意,这样做可能会导致以下不良行为:

  • 会话状态

    会话跟踪当前数据库、架构和角色。如果一个线程更改了这些值(如 USE DATABASE),则其他线程可能会受到影响。这种影响尤其重要,因为更改为具有相同表的另一个架构可能会导致线程意外修改错误的表。此外,更改一个会话中的连接或配置参数可能会影响所有使用该会话的线程。

  • 事务状态

    事务可能在一个会话中启动。如果多个线程可以访问该会话,则每个线程都可能修改同一事务中的数据,这可能会导致在提交或回滚事务时意外保留或丢失数据。

  • 序列计数器

    驱动程序使用序列计数器重试请求。由于序列计数器对于会话来说是全局的,因此在不同线程中重用会话还可能会无意更改全局序列计数器,从而导致重试请求时不可预知的行为。

  • 查询上下文缓存

    为提高性能,会话会跟踪特定于驱动程序的缓存或内部缓存中的一些内部信息。缓存在每次查询后都会更新,因此在会话中同时运行多个查询可能会导致数据损坏。

  • 上次查询 ID

    连接跟踪上次查询 ID,然后可以检索和使用。如果两个查询在不同的线程中并行运行,则竞争条件可能会影响哪个设置上次查询 ID。

Snowflake 建议

  • 尽可能使用连接池。

    如果跨线程重用连接以避免频繁进行身份验证,则应考虑使用连接池。使用连接池可以减少身份验证请求的数量,因为会话在结束时不会关闭 – 它只是返回到池中,在其中它已准备好在下一次使用。即使在使用连接池时,您的应用程序也注意不要更改或重置仅影响特定查询或当前数据库的参数。此外,在将连接返回到连接池之前,应用程序还负责提交或中止活动事务。

  • 谨慎使用异步查询。

    在单个连接上同时启动多个异步查询,或者在异步查询仍在进行时启动同步查询,可能会导致竞争情况,从而导致不可预知的结果。

  • 使用其他身份验证优化。

    特定驱动程序支持以下部分或全部优化,您可以使用这些优化来提高身份验证性能:

    • SSO 令牌缓存

    • MFA 令牌缓存

    • TOML 配置文件中的令牌

    • 自定义令牌访问器

    您应该查看驱动程序文档,了解驱动程序支持哪些选项。

  • 禁用查询上下文缓存。

    如果您知道在多个线程中重用会话和连接时存在的所有问题,但仍想使用它们,Snowflake 建议您在连接定义中将 DisableQueryContextCache 参数设置为 false

语言: 中文