遇到并发和 SQL 事务问题。我有下面的(存根)代码(为了清楚起见,删除了错误检查和此类代码):
dao, _ := sql.Open("postgres", args)
tx1 := dao.Begin()
res, _ := tx1.Exec("UPDATE <...>", args...)
// error check
tx2 := dao.Begin()
res, _ = tx2.Exec("UPDATE <same>", args...)
_ = tx1.Commit()
_ = tx2.Commit()
Run Code Online (Sandbox Code Playgroud)
这发生在单元测试中。这个想法是强制并发失败,因为两个 Exec 正在尝试更新同一行,以确保给出正确的冲突错误响应。然而,第二个 Exec 永久阻塞。
据我所知,只有当数据库没有数据库连接时才会发生这种类型的阻塞,但是事务都应该在它们自己的(独占)连接中运行,并且我没有在任何地方设置最大连接(我也尝试过将其设置为 100 之类的值,但没有效果)。
这是奇怪的部分。如果我将 tx2 Exec() 和 Commit() 分离到一个带有同步通道的单独 goroutine 中,以阻止主线程运行 tx1.Commit() 直到 tx2 运行它的 Exec() ,同样的事情会发生,无限期地阻塞tx2.Exec()。如果我使用 time.Sleep() 而不是同步通道,则 tx2.Exec 会阻塞,直到睡眠完成并且 tx1.Commit() 运行,然后完成并出现预期错误 ( pq: could not serialize access due to concurrent update
)
我是否遗漏了有关 golang 的 SQL 包或 postgres …
我们的应用程序使用odbc驱动程序来访问 Impala 数据库。我们发现,在某些难以复制的情况下,驱动程序将在其 cgo 代码中触发段错误,一旦它通过驱动程序传播回我们的代码,就会表现为致命错误。由于我们希望在这些情况下进行一些清理和警报,因此我实现了一个延迟的恐慌捕捉器,希望这可以捕捉到它们。
但是,它不起作用。致命错误继续直接经过包含调用的延迟函数recover()
(因此显然这不是恐慌,尽管打印输出看起来相似),尽管它确实捕获了其他恐慌。github 问题表明无法捕获 cgo 信号,并且如果发生这种情况,应用程序应该立即崩溃。对于我们的生产应用程序来说,这是一个不可接受的崩溃案例,所以我想知道过去 6 年来这种情况是否发生了变化,或者是否有人知道在出现 cgo 信号时运行一些清理代码的另一种方法。根本无法捕获和处理这些致命错误,这似乎是极其糟糕的设计。
我在代码中创建了一个客户类型。我有一个函数,它正在读取一个 csv 文件并从每一行创建一个数组。
type DesiredService struct {
Name string `json:"Name"`
Status string `json:"Status"`
}
Run Code Online (Sandbox Code Playgroud)
如果我打印出变量,我有一些看起来像
[{app1 active}{app2 active}]
我不知道如何获取该变量并遍历每个索引。我需要获取状态为 active 的所有条目并调用另一个函数来根据 API 检查名称。我在想也许我没有正确设置结构。
当我检查它返回的变量类型时 []main.DesiredService
在阅读了一些文档后,这就是我想出的不起作用的东西。
func checkPagerDutyforService (serviceList []DesiredService) (bool){
var serviceExist bool()
for i, v := range serviceList {
if v == "active" {
checkIfServiceExist(i, serviceList)
serviceExist = true
} else {
if v != "active"{
serviceExist = false
}
}
}
return serviceExist
Run Code Online (Sandbox Code Playgroud)