当前位置:   article > 正文

Postgresql数据库死锁_sharelock on transaction

sharelock on transaction

死锁报错1

UPDATE deadlock_example SET value = value + 1 WHERE id = 1
  • 1

ERROR: deadlock detected
DETAIL: Process 95 waits for ShareLock on transaction 3553457; blocked by process 187.
Process 187 waits for ShareLock on transaction 3553458; blocked by process 95.
HINT: See server log for query details.
CONTEXT: while updating tuple (0,6) in relation “deadlock_example”

其中 Process 95 在等待共享锁(ShareLock)的事务 3553457,而 Process 187 在等待共享锁的事务 3553458。这两个事务相互阻塞,形成了死锁。
具体解释如下:
Process 95 正在等待事务号为 3553457 的共享锁,但被 Process 187 阻塞。
Process 187 正在等待事务号为 3553458 的共享锁,但被 Process 95 阻塞。
这种相互等待的情况导致了死锁。在这种情况下,PostgreSQL 选择其中一个事务(在这里是 Process 95)作为死锁牺牲者,回滚该事务以解除死锁。

死锁报错2

UPDATE deadlock_example SET value = value + 1 WHERE id = 1
  • 1

ERROR: current transaction is aborted, commands ignored until end of transaction block

这个错误消息表明在事务中发生了一个错误,导致整个事务被中止。在 PostgreSQL 中,一旦事务发生错误,该事务就会被中止,后续的命令将被忽略,直到事务块结束。

查看数据库表信息:

SELECT pid, datname, usename, query, state
FROM pg_stat_activity
  • 1
  • 2

在这里插入图片描述

  • stateidle in transaction (aborted),表示连接处于事务中空闲状态,并且事务已中止(aborted)。

这种状态通常表示连接在事务中执行了某些操作,但由于某些原因,该事务已经中止。在这个特定的情况下,连接正在执行一个 UPDATE 查询,但由于死锁等原因,事务中止了。

解决办法

使用 PostgreSQL 中的 pg_terminate_backend 函数可以终止指定的连接。
在 pg_stat_activity 表中查找要终止的连接的进程ID (pid)。在我的情况中,pid 为 95 的连接发生了死锁,所以你可以选择终止该连接。
执行如下命令:

SELECT pg_terminate_backend(95);
  • 1

返回结果为 t ,表示执行成功。
在这里插入图片描述

SELECT pg_terminate_backend(187);
  • 1

在这里插入图片描述
再次查看pg_stat_activity信息,pid为95的进程已经不见了
在这里插入图片描述
再次执行刚才报错的sql,发现可以成功执行了。
在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/511794
推荐阅读
相关标签
  

闽ICP备14008679号