数据库锁问题

Olivia的小跟班 Lv4

题记

​ 今天在公司遇见了一个数据库锁问题,复盘一下。

问题与原因

​ 测试环境下更新Spine接口:biz层使用ExecTx调用data层的一些函数用于数据库操作,其中更新文件时间戳的代码如下所示,其他都是使用c.db.DB(ctx)来实现数据库操作,这可能会出现更新文件时间戳操作使用的 gorm.DB 实例和其他的不同,导致事务不一致的问题。(我就遇见了执行到更新文件时间戳函数卡住的情况,锁等待)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
func (c *createRepo) UpdatePropVersionTsByFileID(ctx context.Context, fileID string, versionTs int64) error {
var err error
err =c.db.Model(&schema.CreateHubProp{}).Where("file_id=?", fileID).Updates(&schema.CreateHubProp{VersionTs: versionTs}).Error
if err != nil {
c.log.Error("UpdateVersionTsByFileID err: ", err)
return err
}

return nil
}


func (d *Data) DB(ctx ...context.Context) *gorm.DB {
if len(ctx) == 1 {
tx, ok := ctx[0].Value(contextTxKey{}).(*gorm.DB)
if ok {
return tx
}
}
return d.db
}

解决方案

​ 首先使用下面语句查询是否和我们想的一样,事务不一致导致的上述问题。

1
SELECT * FROM pg_stat_activity WHERE datname = '数据库' AND wait_event_type = 'Lock';//检索有关当前等待锁的活动信息。这个查询能够帮助你诊断数据库中的锁等待问题

​ 然后看查询之后wait_event字段的值是什么 ,由于目前在家,这个复盘不是在公司现场做的,忘记具体的值,隐约记得的是transactionid( 这个会话在等待事务 ID 锁定,这可能是因为另一个会话正在进行事务操作),以下是GPT的解释,一看好像确实我应该是这样的问题🤣。

image-20240830005037235

​ 根据上面命令查到的pid字段,使用以下命令终止它,同时修改代码。

1
2
3
SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE pid = <your_pid>;
1
err=c.DB(ctx).Model(&schema.CreateHubProp{}).Where("file_id=?", fileID).Updates(&schema.CreateHubProp{VersionTs: versionTs}).Error
  • 标题: 数据库锁问题
  • 作者: Olivia的小跟班
  • 创建于 : 2024-08-29 23:07:50
  • 更新于 : 2024-08-30 00:57:20
  • 链接: https://www.youandgentleness.cn/2024/08/29/上班遇见的数据库锁问题/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论
此页目录
数据库锁问题