英文:
SQL query hangs or crashes
问题
以下是Go 1.16.6上的代码,最后一个Exec调用hang住(如果从不同的goroutine调用相同的函数,则会崩溃)。
两个库 "github.com/mattn/go-sqlite3" 和 "modernc.org/sqlite" 给出相同的结果
package main
import (
"os"
"testing"
"database/sql"
_ "github.com/mattn/go-sqlite3"
// _ "modernc.org/sqlite"
)
func Test_Bug3(t *testing.T) {
DBPath := "test.db"
os.Remove(DBPath)
DB, err := sql.Open("sqlite3", DBPath)
if err != nil {
t.Fatalf("%s: %v", DBPath, err)
}
if _, err := DB.Exec(`CREATE TABLE IF NOT EXISTS verdictcache (sha1 text);`); err != nil {
t.Fatalf("%s: %v", DBPath, err)
}
_, err = DB.Exec("INSERT OR REPLACE INTO verdictcache (sha1) VALUES ($1)", "a")
if err != nil {
t.Fatalf("%s: %v", DBPath, err)
}
_, err = DB.Query("SELECT * FROM verdictcache WHERE sha1=$1", "a")
if err != nil {
t.Fatalf("%s: %v", DBPath, err)
}
_, err = DB.Exec("INSERT OR REPLACE INTO verdictcache (sha1) VALUES ($1)", "b")
if err != nil {
t.Fatalf("%s: %v", DBPath, err)
}
}
英文:
Following code on Go 1.16.6 hangs on last Exec call (or crashes if same functions are called from different goroutines)
Both libraries "github.com/mattn/go-sqlite3" and "modernc.org/sqlite" give same results
package main
import (
"os"
"testing"
"database/sql"
_ "github.com/mattn/go-sqlite3"
// _ "modernc.org/sqlite"
)
func Test_Bug3(t *testing.T) {
DBPath := "test.db"
os.Remove(DBPath)
DB, err := sql.Open("sqlite3", DBPath)
if err != nil {
t.Fatalf("%s: %v", DBPath, err)
}
if _, err := DB.Exec(`CREATE TABLE IF NOT EXISTS verdictcache (sha1 text);`); err != nil {
t.Fatalf("%s: %v", DBPath, err)
}
_, err = DB.Exec("INSERT OR REPLACE INTO verdictcache (sha1) VALUES ($1)", "a")
if err != nil {
t.Fatalf("%s: %v", DBPath, err)
}
_, err = DB.Query("SELECT * FROM verdictcache WHERE sha1=$1", "a")
if err != nil {
t.Fatalf("%s: %v", DBPath, err)
}
_, err = DB.Exec("INSERT OR REPLACE INTO verdictcache (sha1) VALUES ($1)", "b")
if err != nil {
t.Fatalf("%s: %v", DBPath, err)
}
}
答案1
得分: 3
发生的情况几乎可以确定是您没有调用Close()
(或以其他方式消耗了结果)DB.Query(...)
返回的结果。
尝试:
func Test_Bug3(t *testing.T) {
DBPath := "test.db"
os.Remove(DBPath)
DB, err := sql.Open("sqlite3", DBPath)
if err != nil {
t.Fatalf("%s: %v", DBPath, err)
}
if _, err := DB.Exec(`CREATE TABLE IF NOT EXISTS verdictcache (sha1 text);`); err != nil {
t.Fatalf("%s: %v", DBPath, err)
}
_, err = DB.Exec("INSERT OR REPLACE INTO verdictcache (sha1) VALUES ($1)", "a")
if err != nil {
t.Fatalf("%s: %v", DBPath, err)
}
res, err := DB.Query("SELECT * FROM verdictcache WHERE sha1=$1", "a")
if err != nil {
t.Fatalf("%s: %v", DBPath, err)
}
res.Close()
_, err = DB.Exec("INSERT OR REPLACE INTO verdictcache (sha1) VALUES ($1)", "b")
if err != nil {
t.Fatalf("%s: %v", DBPath, err)
}
}
英文:
What is happening is almost certainly that you did not call Close()
(or otherwise consumed the rows) on the result returned by DB.Query(...)
.
Try:
func Test_Bug3(t *testing.T) {
DBPath := "test.db"
os.Remove(DBPath)
DB, err := sql.Open("sqlite3", DBPath)
if err != nil {
t.Fatalf("%s: %v", DBPath, err)
}
if _, err := DB.Exec(`CREATE TABLE IF NOT EXISTS verdictcache (sha1 text);`); err != nil {
t.Fatalf("%s: %v", DBPath, err)
}
_, err = DB.Exec("INSERT OR REPLACE INTO verdictcache (sha1) VALUES ($1)", "a")
if err != nil {
t.Fatalf("%s: %v", DBPath, err)
}
res, err := DB.Query("SELECT * FROM verdictcache WHERE sha1=$1", "a")
if err != nil {
t.Fatalf("%s: %v", DBPath, err)
}
res.Close()
_, err = DB.Exec("INSERT OR REPLACE INTO verdictcache (sha1) VALUES ($1)", "b")
if err != nil {
t.Fatalf("%s: %v", DBPath, err)
}
}
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论