BigQuery BadRequest('由于并发更新而无法序列化访问')

Posted

技术标签:

【中文标题】BigQuery BadRequest(\'由于并发更新而无法序列化访问\')【英文标题】:BigQuery BadRequest('Could not serialize access due to concurrent update')BigQuery BadRequest('由于并发更新而无法序列化访问') 【发布时间】:2021-12-07 10:58:09 【问题描述】:

所以我尝试像这样更新多行(至少 50 行),这将导致时间超过 2 分钟(慢):

query_job_list = []

for data in data_list:
    update statement = ...
    query_job = client.query(update_statement)
    query_job_list.append(query_job)

for query_job in query_job_list:
    query_job.result()

执行上述代码会导致:

BadRequest('Could not serialize access due to concurrent update')

我记得它已被锁定,因此在作业仍在运行时我们无法更新。 (对不起,不是 SQL 专家)

我只是想知道在 Bigquery 上更新多行的最快方法是什么?

【问题讨论】:

BQ 不适合高水平的单个行级更新(相对于事务数据库 mysql、PostGreSQL 等)。您将希望将所有新值放在一个 select 语句中并一次更新它们。您没有包含更新声明的示例,因此很难说出您在做什么。查看cloud.google.com/bigquery/docs/reference/standard-sql/… 嗨@Tenserflu,如果我的回答解决了您的问题,请考虑接受并支持它。如果没有,请告诉我,以便我改进答案。 【参考方案1】:

由于并发更新,您会看到该错误。此问题通常发生在对表有多个并发更新时,变异的 DML 查询(UPDATE、MERGE、DELETE)同时运行并因此可能相互冲突。对于变异 DML,为了保持一致性,如果有多个查询大致同时运行,其中一个可能会失败。请参阅此doc,了解有关用于变异 DML 的 DML 并发以及 Google 推荐的模式以获得更好性能的更多信息。

我的建议是将 DML 操作分配给不同的表,这样它们就不会同时对同一个表进行操作,或者仅在前一个表完成后才开始另一个表。此外,正如@rtenha 在评论中提到的那样,避免提交大量单独的行更新或插入。相反,尽可能将 DML 操作组合在一起。

【讨论】:

以上是关于BigQuery BadRequest('由于并发更新而无法序列化访问')的主要内容,如果未能解决你的问题,请参考以下文章

访问由电子表格支持的bigquery表时出现BadRequest / ForbiddenException异常

访问由电子表格支持的 bigquery 表时遇到 BadRequest/ForbiddenException

无法使用 BigQuery Python API 设置目标表

加载时间戳时出现 Bigquery 错误

bigquery 是不是保持并发性?

Google BigQuery 中的参数化查询错误