【问题标题】:Dead Lock in golang database/sqlgolang数据库/sql中的死锁
【发布时间】:2016-06-11 23:20:21
【问题描述】:

我注意到 Go 的 database/sql 包中有一个奇怪的行为,使用的是 lib/pq 中的 PostgreSQL 驱动程序。基本上,如果我在同一连接上构建事务时使用数据库连接进行查询,我会进入死锁并且程序阻塞(我需要手动重新启动数据库服务器以使其再次工作)。在下面的示例代码中,我会卡在 select 语句中,并且永远不会执行第二个 insert 语句(而如果我删除查询,代码将正常执行)。

tx, _ := connection.Begin()
tx.Exec(insert_statement)
rows, _ := connection.Query(select_statement)
rows.Close()
tx.Exec(insert_statement_2)
tx.Commit()

这正常吗?每次我想使用事务时都应该创建一个新的数据库连接吗?

【问题讨论】:

    标签: database go deadlock


    【解决方案1】:

    connection.Query 函数不会与您的 tx.XXX 函数在同一会话上执行,因此如果 select_statement 碰巧引用了 insert_statement 写入的任何内容,您可能会阻塞。

    尝试 tx.Query(select_statement) 看看是否阻塞。

    【讨论】:

    • 是的,tx.Query() 会起作用,但我不能总是控制它。事务 tx 用于由管理员对数据库进行一些更新,而查询由访问网站的用户调用。所以这两件事可能同时发生,如果它没有关闭我的数据库,我更愿意!
    • 我只希望这在同一个 goroutine 中背靠背执行时会死锁。当不同的例程执行不同的各种事情时,您会遇到这个问题吗?此外,除非您执行“for update”,否则 postgresql SELECT 语句不会锁定,您这样做了吗?
    • 我没有在不同的 goroutine 上测试过它,我试图通过在同一个线程上做不同的事情来天真地复制并发行为,但这可能不是一个好方法。 select 语句只是一个普通的“select * from mytable”,其中相同的“mytable”被之前的插入修改了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-17
    • 2012-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-19
    • 1970-01-01
    相关资源
    最近更新 更多