40P01 — deadlock_detected:检测到死锁
检测到死锁,事务因等待环被选为受害者中止。
英文手册覆盖始于 PostgreSQL 8.1. 来源历史与运行验证各自保留独立版本边界。
当前阅读 PG 18·选择有来源记录的版本
- aliases
- 未知
- class name
- Transaction Rollback
- condition name
- deadlock_detected
- lang
- en
- sqlstate
- 40P01
版本定义 PG 18
速览 {#at-a-glance}
40P01 是 PostgreSQL 类别 40 transaction_rollback 中的 deadlock_detected 条件。它表示锁管理器发现事务之间形成等待环,因此选择一个受害事务并中止它。
主报文是 deadlock detected。服务器可能附带动态构造的等待图 detail、提示查看服务器日志的 hint,以及说明被中断语句的上下文。进程 ID、事务 ID 和具体等待图都随运行变化;应按 SQLSTATE 分支并保存结构化字段,不要匹配这些动态值。
代表性案例先让两个会话分别持有相反的行锁,再用 threading.Barrier 放行两个交叉请求,同时由独立观察会话采样 pg_stat_activity 的 wait_event_type=Lock。观察会话不负责放行请求。一个会话收到 40P01 后事务为 INERROR;幸存会话完成操作,随后两个会话都回到 IDLE。新的事务按顺序取得两把行锁并提交完整重试。
运行 40P01-manual-boundary-final-20260909 在 PostgreSQL 18.6 和隔离的 PostgreSQL 10.21 上均通过。逐目标断言和结构化观察保存在公开证据 JSON中。
含义与触发路径 {#meaning}
死锁需要等待图中出现环。常见形式是会话 A 锁住第 1 行后请求第 2 行,同时会话 B 锁住第 2 行后请求第 1 行。PostgreSQL 的死锁检测器会在配置的 deadlock timeout 到期后检查锁图,DeadLockReport 随后报告该条件。
这个错误说明事务协调失败,不表示行数据损坏。受害事务的全部工作都会中止。另一个事务可能在检测器打破环后继续,但它成功完成并不意味着受害事务的预期工作已经应用。
40P01 不等于最终成功的锁等待,也不同于由 statement timeout 引起的 57014。本案例观察到的 pg_stat_activity 锁等待用于证明死锁准备顺序;服务器返回的 deadlock detected 才是最终条件。
报文与诊断 {#messages}
下面的调度是代表性操作。应在两个连接上分别执行会话 A 和 B;两个会话先各自持有一把行锁,随后由 barrier 放行交叉请求,独立观察会话在请求等待期间采样两个 backend。观察会话不是放行条件。
CREATE TABLE locks(id integer PRIMARY KEY, marker text NOT NULL);
INSERT INTO locks VALUES (1, 'seed-1'), (2, 'seed-2');
-- 会话 A:开始事务、设置 deadlock_timeout,并锁住 id = 1。
BEGIN;
SET deadlock_timeout = '100ms';
UPDATE locks SET marker = 'first-1' WHERE id = 1;
-- 会话 B:开始事务、设置 deadlock_timeout,并锁住 id = 2。
BEGIN;
SET deadlock_timeout = '100ms';
UPDATE locks SET marker = 'second-2' WHERE id = 2;
-- 明确的 barrier 让两个请求同时进入锁循环。
UPDATE locks SET marker = 'first-2' WHERE id = 2;
UPDATE locks SET marker = 'second-1' WHERE id = 1;
-- 受害事务必须 ROLLBACK;幸存事务可以 COMMIT。
ROLLBACK;
COMMIT;
-- 新的重试连接按同一顺序取得锁,并验证两行。
BEGIN;
UPDATE locks SET marker = 'retry-1' WHERE id = 1;
UPDATE locks SET marker = 'retry-2' WHERE id = 2;
COMMIT;
SELECT id, marker FROM locks ORDER BY id;
PostgreSQL 18.6 对受害事务返回的形状为:
SQLSTATE: 40P01
severity: ERROR
message_primary: deadlock detected
message_detail: Process <pid-a> waits for ShareLock on transaction <xid-b>; blocked by process <pid-b>.
Process <pid-b> waits for ShareLock on transaction <xid-a>; blocked by process <pid-a>.
message_hint: See server log for query details.
context: while updating tuple (0,2) in relation "locks"
source: deadlock.c / DeadLockReport / line 1138
PG10 运行得到相同的主报文和字段,但源码行号随版本变化。detail 来自实时等待图,因此此处用运行时占位符表示进程和事务标识。hint 并不保证客户端一定收到对应的服务器日志条目,它是在日志已配置时指向调查位置。
诊断 {#diagnosis}
记录 SQLSTATE、严重级别、主报文、detail、hint、上下文、失败语句、backend PID 和事务状态。在等待仍存在时检查 pg_stat_activity 及相关锁视图。有用的观察应包含 wait_event_type=Lock、等待事件、当前查询和参与的 PID;单纯 sleep 不能建立死锁证据。
应根据实际应用代码及所有访问同一行或 advisory lock 的路径整理加锁顺序,并检查触发器、外键、索引或后台 worker 是否取得了额外的锁。deadlock_timeout 只控制何时检测,调大它会改变检测延迟,不能消除等待环。
错误发生后,受害连接必须先 ROLLBACK,因为此时为 INERROR;幸存连接在提交前可能为 INTRANS。runner 验证了显式清理后两者都回到 IDLE,并在重试前读取了数据。
处理与修复 {#response}
回滚受害事务并释放其锁,再选择完整修复:
- 让所有代码路径按一致顺序取得同一组锁,最好显式排序键值。
- 缩短事务,不要在持有数据库锁时等待外部工作。
- 只有在操作可重复且结果具备幂等语义时,才从头重试整个事务,包括读取和加锁。
- 重试后验证已提交的业务结果;幸存事务的部分更新不能证明受害事务的工作成功。
本案例的修复按顺序锁定第 1 行和第 2 行,提交 retry-1、retry-2,并在连接为 IDLE 时读取两行。生产实现仍需有限的重试预算和应用级幂等键;单凭 SQLSTATE 不能判断重复操作是否安全。
版本与边界 {#versions}
目录在 PostgreSQL 7.4 的锁定定义中已观察到 40P01,并持续到 8.4.22 的 pre-9.0 定义;随后在列出的所有正式快照直到 PostgreSQL 18.6 以及 PostgreSQL 19 Beta 3 预览中存在。这是 definition_only 的存在边界,不是确切实现引入版本或运行时使用断言。9.0 头文件视图到 9.1 文本定义之间记录了类别标题变化;这只是目录观察,不是代码引入日期。扫描范围内条件行没有其他定义变化。
双会话案例在 PostgreSQL 18.6 和 10.21 上均通过。检测时点、锁类型和 detail 取决于工作负载与设置;本页采用 SQLSTATE 及事务回滚要求作为兼容边界,而不是固定的进程 ID detail。
相关 {#related}
40001 — serialization_failure 同样要求从新快照开始重试完整事务。57014 — query_canceled 表示取消,不表示锁环。23503 — foreign_key_violation 和 23505 — unique_violation 是可能出现在锁顺序需要复核的事务中的完整性条件。25P02 — in_failed_sql_transaction 是受害事务中止后出现的后续状态。
来源 {#sources}
结构化证据记录在公开证据 JSON中。所有源码记录固定到 PostgreSQL commit 724edf9bde9d356724ad384a2e196edc3c9f80f7;运行记录保留各目标的精确 ID 和结构化观察。
src.errcodes.18.6—errcodes.txtsrc.deadlock.18.6—deadlock.cdoc.mvcc.18— 死锁与序列化失败- Runtime:latest 与 pg10 均为
40P01-manual-boundary-final-20260909,结构化观察见公开证据 JSON
比较版本
SQLSTATE 证据与已记录的运行版本
cases · two_session_lock_cycle
{
"assertions": [
"One statement receives 40P01",
"The victim transaction is rolled back",
"The surviving session can finish with one coherent update per row",
"A post-victim retry takes locks in order and commits the complete repair"
],
"case_id": "two_session_lock_cycle",
"cleanup": "Roll back workers and drop the case schema.",
"has_snippet": true,
"position": 0,
"preconditions": [
"Two sessions",
"Two rows",
"Both sessions acquire one row lock before attempting the other"
],
"repair": "Keep lock order consistent; after rollback, retry the complete idempotent transaction in that order and verify its committed result.",
"trigger": "Each session requests the row held by the other, using a barrier and observed lock waits.",
"versions": [
"10",
"18"
]
}claims · identity.class-and-condition
{
"claim_id": "identity.class-and-condition",
"limits": "Directory identity does not identify the lock graph or the selected victim.",
"method": "Read the Class 40 section and 40P01 row in the frozen errcodes.txt snapshot.",
"position": 0,
"runtime": [],
"sources": [
"src.errcodes.18.6"
],
"statement": "40P01 is the deadlock_detected condition in Class 40 transaction_rollback."
}claims · mechanism.deadlock-report
{
"claim_id": "mechanism.deadlock-report",
"limits": "The detail contains live process and transaction identifiers and is not a fixed user-facing template.",
"method": "Trace DeadLockReport and compare the primary message, dynamic detail, hint, and source location in the victim diagnostic.",
"position": 1,
"runtime": [],
"sources": [
"src.deadlock.18.6",
"doc.protocol.18"
],
"statement": "The deadlock detector reports deadlock detected with a dynamically assembled wait-graph detail and the hint See server log for query details."
}claims · runtime.cycle-and-recovery
{
"claim_id": "runtime.cycle-and-recovery",
"limits": "The survivor's winner can differ by timing; the run proves the controlled cycle and recovery, not a universal victim-selection rule.",
"method": "Use an explicit barrier, observe transactionid Lock waits through pg_stat_activity, then inspect worker diagnostics, transaction states, and surviving rows.",
"position": 2,
"runtime": [],
"sources": [
"doc.mvcc.18",
"case-manifest.40P01",
"runtime.40P01-manual-boundary-final-20260909.latest",
"runtime.40P01-manual-boundary-final-20260909.pg10"
],
"statement": "An explicit two-session lock cycle produced one 40P01 victim in INERROR, left one coherent survivor transaction, and allowed the victim to recover with ROLLBACK."
}claims · runtime.complete-retry
{
"claim_id": "runtime.complete-retry",
"limits": "A fixed ordered update is a repair proof for this case; application retries still need complete business-operation and idempotency review.",
"method": "Run the retry statements in primary-key order on a fresh transaction and assert IDLE plus both post-retry rows.",
"position": 3,
"runtime": [],
"sources": [
"doc.mvcc.18",
"snippet-registry.40P01.final",
"runtime.40P01-registry-final-20260909.latest",
"runtime.40P01-registry-final-20260909.pg10",
"runtime.40P01-manual-boundary-final-20260909.latest",
"runtime.40P01-manual-boundary-final-20260909.pg10"
],
"statement": "After the deadlock cleanup, an ordered retry transaction updated both rows, committed, and produced retry-1 and retry-2."
}claims · versions.catalogue-boundary
{
"claim_id": "versions.catalogue-boundary",
"limits": "The first scanned release is a lower bound, not an asserted introduction version.",
"method": "Read the manifest snapshots and definition references for the code.",
"position": 4,
"runtime": [],
"sources": [
"manifest.40P01"
],
"statement": "The locked catalogue records 40P01 in every listed formal snapshot from 9.0.23 through 18.6 and in 19beta3; pre-9.0 history is not scanned."
}messages · message.deadlock-report
{
"limits": "The source passes the assembled client wait graph through errdetail_internal(\"%s\", clientbuf.data); process, transaction, relation, and tuple values vary by run.",
"message_id": "message.deadlock-report",
"path": "",
"position": 0,
"raw": {
"detail_template": "%s",
"detail_type": "dynamic wait graph",
"hint_template": "See server log for query details.",
"id": "message.deadlock-report",
"limits": "The source passes the assembled client wait graph through errdetail_internal(\"%s\", clientbuf.data); process, transaction, relation, and tuple values vary by run.",
"primary_template": "deadlock detected",
"severity_source": "explicit ERROR",
"sources": [
"src.deadlock.18.6"
],
"sqlstate": "40P01"
},
"severity": "explicit ERROR",
"sources": [
"src.deadlock.18.6"
],
"templates": [
{
"kind": "primary",
"literal": "deadlock detected",
"position": 0,
"role": "",
"template": "deadlock detected"
},
{
"kind": "detail",
"literal": "",
"position": 1,
"role": "",
"template": "%s"
},
{
"kind": "hint",
"literal": "See server log for query details.",
"position": 2,
"role": "",
"template": "See server log for query details."
}
]
}runtimes · runtime.40P01-registry-final-20260909.latest · 18.6 (Homebrew) · passed
{
"cases": [
"two_session_lock_cycle"
],
"limits": "",
"position": 0,
"raw": {
"cases": [
"two_session_lock_cycle"
],
"id": "runtime.40P01-registry-final-20260909.latest",
"observed": {
"lock_wait": {
"wait_event": "transactionid",
"wait_event_type": "Lock"
},
"retry": {
"rows": [
[
1,
"retry-1"
],
[
2,
"retry-2"
]
],
"status": "IDLE"
},
"rows_before_retry": [
[
1,
"first-1"
],
[
2,
"first-2"
]
],
"statuses": {
"survivor": "IDLE",
"victim_after_error": "INERROR",
"victim_after_rollback": "IDLE"
},
"synchronization": "Both workers first held one row lock; a barrier then released the two cross-row requests, while an independent observer sampled the transactionid lock waits. The observer did not release the requests.",
"victim": {
"message_hint": "See server log for query details.",
"message_primary": "deadlock detected",
"severity": "ERROR",
"source_file": "deadlock.c",
"source_function": "DeadLockReport",
"source_line": "1138",
"sqlstate": "40P01",
"worker": "second"
}
},
"raw": "verify/results/40P01-registry-final-20260909/latest/raw.jsonl",
"raw_sha256": "bdfda4fc40404195f34d3297cf71eebdd2146ea44bf91fc58484498455a5953d",
"run_id": "40P01-registry-final-20260909",
"server_version": "18.6 (Homebrew)",
"server_version_num": 180006,
"snippet_registry": {
"path": "verify/cases/40P01/snippets.json",
"sha256": "71a3377497dc2c1ba5b71c9ba81f71fc3cff975fcd245613ba2ddb82857c0591"
},
"status": "passed",
"summary": "verify/results/40P01-registry-final-20260909/latest/summary.json",
"summary_sha256": "693bc9cc5696cbb892eb12808a2b15db875c52aad5961410f59679df63566c07",
"target": "latest"
},
"run_id": "40P01-registry-final-20260909",
"runtime_id": "runtime.40P01-registry-final-20260909.latest",
"server_version": "18.6 (Homebrew)",
"status": "passed",
"target": "latest"
}runtimes · runtime.40P01-registry-final-20260909.pg10 · 10.21 (Debian 10.21-1.pgdg90+1) · passed
{
"cases": [
"two_session_lock_cycle"
],
"limits": "",
"position": 1,
"raw": {
"cases": [
"two_session_lock_cycle"
],
"id": "runtime.40P01-registry-final-20260909.pg10",
"image": "postgres@sha256:b2baf8998630663d21370da06387c950e587071bdd307ee34e661cdcc7442bcc",
"observed": {
"lock_wait": {
"wait_event": "transactionid",
"wait_event_type": "Lock"
},
"retry": {
"rows": [
[
1,
"retry-1"
],
[
2,
"retry-2"
]
],
"status": "IDLE"
},
"rows_before_retry": [
[
1,
"second-1"
],
[
2,
"second-2"
]
],
"statuses": {
"survivor": "IDLE",
"victim_after_error": "INERROR",
"victim_after_rollback": "IDLE"
},
"synchronization": "Both workers first held one row lock; a barrier then released the two cross-row requests, while an independent observer sampled the transactionid lock waits. The observer did not release the requests.",
"victim": {
"message_hint": "See server log for query details.",
"message_primary": "deadlock detected",
"severity": "ERROR",
"source_file": "deadlock.c",
"source_function": "DeadLockReport",
"source_line": "1146",
"sqlstate": "40P01",
"worker": "first"
}
},
"raw": "verify/results/40P01-registry-final-20260909/pg10/raw.jsonl",
"raw_sha256": "33e4c878282a503d074da04aaceb11f0aa5d0a245cac601562a5ea847cd45f63",
"run_id": "40P01-registry-final-20260909",
"server_version": "10.21 (Debian 10.21-1.pgdg90+1)",
"server_version_num": 100021,
"snippet_registry": {
"path": "verify/cases/40P01/snippets.json",
"sha256": "71a3377497dc2c1ba5b71c9ba81f71fc3cff975fcd245613ba2ddb82857c0591"
},
"status": "passed",
"summary": "verify/results/40P01-registry-final-20260909/pg10/summary.json",
"summary_sha256": "ff489619acc2047333c05a4d565a0ad4c993a762b8c4abca3fe684cd8928cf0c",
"target": "pg10"
},
"run_id": "40P01-registry-final-20260909",
"runtime_id": "runtime.40P01-registry-final-20260909.pg10",
"server_version": "10.21 (Debian 10.21-1.pgdg90+1)",
"status": "passed",
"target": "pg10"
}runtimes · runtime.40P01-manual-boundary-final-20260909.latest · 18.6 (Homebrew) · passed
{
"cases": [
"two_session_lock_cycle"
],
"limits": "This run proves the registry BEGIN/COMMIT/ROLLBACK statements for both lock-cycle sessions and the ordered retry execute with autocommit=True; worker synchronization still uses barriers and observed lock waits.",
"position": 2,
"raw": {
"cases": [
"two_session_lock_cycle"
],
"id": "runtime.40P01-manual-boundary-final-20260909.latest",
"limits": "This run proves the registry BEGIN/COMMIT/ROLLBACK statements for both lock-cycle sessions and the ordered retry execute with autocommit=True; worker synchronization still uses barriers and observed lock waits.",
"observed": {
"connections_autocommit": {
"first": true,
"retry": true,
"second": true
},
"retry": {
"rows": [
[
1,
"retry-1"
],
[
2,
"retry-2"
]
],
"status": "IDLE"
},
"transaction_control": "Registry BEGIN/COMMIT/ROLLBACK statements run with autocommit=True; no driver implicit BEGIN participates."
},
"raw": "verify/results/40P01-manual-boundary-final-20260909/latest/raw.jsonl",
"raw_sha256": "562a80715a6dcaf4f14d99c54001799e05c3c52353d9e836ab88039f47ce2cb5",
"run_id": "40P01-manual-boundary-final-20260909",
"server_version": "18.6 (Homebrew)",
"server_version_num": 180006,
"snippet_registry": {
"path": "verify/cases/40P01/snippets.json",
"sha256": "71a3377497dc2c1ba5b71c9ba81f71fc3cff975fcd245613ba2ddb82857c0591"
},
"status": "passed",
"summary": "verify/results/40P01-manual-boundary-final-20260909/latest/summary.json",
"summary_sha256": "4d5b1401badd66f6b1c33040d7bbbcfbc68ac611c3a7f508cb29a57bc2d95594",
"target": "latest"
},
"run_id": "40P01-manual-boundary-final-20260909",
"runtime_id": "runtime.40P01-manual-boundary-final-20260909.latest",
"server_version": "18.6 (Homebrew)",
"status": "passed",
"target": "latest"
}runtimes · runtime.40P01-manual-boundary-final-20260909.pg10 · 10.21 (Debian 10.21-1.pgdg90+1) · passed
{
"cases": [
"two_session_lock_cycle"
],
"limits": "This run proves the registry BEGIN/COMMIT/ROLLBACK statements for both lock-cycle sessions and the ordered retry execute with autocommit=True; worker synchronization still uses barriers and observed lock waits.",
"position": 3,
"raw": {
"cases": [
"two_session_lock_cycle"
],
"id": "runtime.40P01-manual-boundary-final-20260909.pg10",
"image": "postgres@sha256:b2baf8998630663d21370da06387c950e587071bdd307ee34e661cdcc7442bcc",
"limits": "This run proves the registry BEGIN/COMMIT/ROLLBACK statements for both lock-cycle sessions and the ordered retry execute with autocommit=True; worker synchronization still uses barriers and observed lock waits.",
"observed": {
"connections_autocommit": {
"first": true,
"retry": true,
"second": true
},
"retry": {
"rows": [
[
1,
"retry-1"
],
[
2,
"retry-2"
]
],
"status": "IDLE"
},
"transaction_control": "Registry BEGIN/COMMIT/ROLLBACK statements run with autocommit=True; no driver implicit BEGIN participates."
},
"raw": "verify/results/40P01-manual-boundary-final-20260909/pg10/raw.jsonl",
"raw_sha256": "c2789c19f9106cf34a49fbfa791fbe0e23706f87e8d8a133abfb360165aa8ee1",
"run_id": "40P01-manual-boundary-final-20260909",
"server_version": "10.21 (Debian 10.21-1.pgdg90+1)",
"server_version_num": 100021,
"snippet_registry": {
"path": "verify/cases/40P01/snippets.json",
"sha256": "71a3377497dc2c1ba5b71c9ba81f71fc3cff975fcd245613ba2ddb82857c0591"
},
"status": "passed",
"summary": "verify/results/40P01-manual-boundary-final-20260909/pg10/summary.json",
"summary_sha256": "1aca5e77935f4066898c72332cb16f06c16f56ccd00414349f21a746d46f6ed8",
"target": "pg10"
},
"run_id": "40P01-manual-boundary-final-20260909",
"runtime_id": "runtime.40P01-manual-boundary-final-20260909.pg10",
"server_version": "10.21 (Debian 10.21-1.pgdg90+1)",
"status": "passed",
"target": "pg10"
}sources · src.errcodes.18.6
{
"commit": "724edf9bde9d356724ad384a2e196edc3c9f80f7",
"docs_url": "",
"kind": "",
"location": "lines 329-334",
"path": "src/backend/utils/errcodes.txt",
"position": 0,
"sha256": "6e8de346643ba84aa3c9c6a73360acfc7b2dfb89162c06c08ce9bf5bcd5bbcba",
"source_id": "src.errcodes.18.6",
"tag": "REL_18_6",
"url": "https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/errcodes.txt"
}sources · src.deadlock.18.6
{
"commit": "724edf9bde9d356724ad384a2e196edc3c9f80f7",
"docs_url": "",
"kind": "",
"location": "lines 1071-1138",
"path": "src/backend/storage/lmgr/deadlock.c",
"position": 1,
"sha256": "f9931d72369a752e5fff5df3b5bfe5ffd47a3f65651522d27cf62f75fac0075f",
"source_id": "src.deadlock.18.6",
"tag": "REL_18_6",
"url": "https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/storage/lmgr/deadlock.c#L1071-L1138"
}sources · doc.mvcc.18
{
"commit": "724edf9bde9d356724ad384a2e196edc3c9f80f7",
"docs_url": "",
"kind": "",
"location": "serialization and deadlock failure handling",
"path": "doc/src/sgml/mvcc.sgml",
"position": 2,
"sha256": "4b7bf77ee0af4b86052330ff2421d567df3604b75fe7d4f522bec84fdea87340",
"source_id": "doc.mvcc.18",
"tag": "PG18-docs",
"url": "https://www.postgresql.org/docs/18/mvcc-serialization-failure-handling.html"
}sources · doc.protocol.18
{
"commit": "724edf9bde9d356724ad384a2e196edc3c9f80f7",
"docs_url": "",
"kind": "",
"location": "ErrorResponse fields",
"path": "doc/src/sgml/protocol.sgml",
"position": 3,
"sha256": "745339e07ebbc2bb67d98b258e25772ada644ef26011e3cd6b3fcbb435235f89",
"source_id": "doc.protocol.18",
"tag": "PG18-docs",
"url": "https://www.postgresql.org/docs/18/protocol-error-fields.html"
}sources · manifest.40P01
{
"commit": "",
"docs_url": "",
"kind": "local_artifact",
"location": "snapshots and definition_blobs entries for the 40P01 definition",
"path": "sources/manifest.lock.json",
"position": 4,
"sha256": "1727a275f336988ff96b4f9990a4ca253080f73fc5d316e7def165c8cf3708a8",
"source_id": "manifest.40P01",
"tag": "",
"url": "../sources/manifest.lock.json"
}sources · case-manifest.40P01
{
"commit": "",
"docs_url": "",
"kind": "local_artifact",
"location": "two_session_lock_cycle",
"path": "verify/cases/40P01/cases.json",
"position": 5,
"sha256": "85a8653680509a53f9d8fa9b08bafa3eeabe78553ef7d1f4e0aaf0ef7a1abe3d",
"source_id": "case-manifest.40P01",
"tag": "",
"url": "../verify/cases/40P01/cases.json"
}sources · snippet-registry.40P01.final
{
"commit": "",
"docs_url": "",
"kind": "local_artifact",
"location": "two_session_lock_cycle ordered SQL",
"path": "verify/cases/40P01/snippets.json",
"position": 6,
"sha256": "71a3377497dc2c1ba5b71c9ba81f71fc3cff975fcd245613ba2ddb82857c0591",
"source_id": "snippet-registry.40P01.final",
"tag": "",
"url": "../verify/cases/40P01/snippets.json"
}来源引用
定义来源
center · PostgreSQL 18 · english-manuals:72247742d92f7f3aaf91240f5e22f29a345fd3f3acdbd0cbe853b5995f934d21
正文语言: zh-Hans · english-manuals:72247742d92f7f3aaf91240f5e22f29a345fd3f3acdbd0cbe853b5995f934d21