gyu*_*asf 6 database sqlite locking go
我正在使用内存中的sqlite,如下所示。
func init() {
global.ConductorConfig = readConfig()
log.Println(utils.GetCurrentDir() + global.ConductorConfig.DbFile)
//db = sqlx.MustConnect("sqlite3", utils.GetCurrentDir()+global.ConductorConfig.DbFile)
db = sqlx.MustConnect("sqlite3", ":memory:")
db.Exec(schema)
task:=model.Task{}
SaveTask(&task)
db.MapperFunc(func(s string) string {
return s
})
}
Run Code Online (Sandbox Code Playgroud)
在我的主函数中,我创建了表
if global.ConductorConfig.DevMode {
db.CreateTables()
}
go job.HeartbeatJob()
go job.TaskClearJob()
app.Action = func(c *cli.Context) error {
ListenAndServe()
return nil
}
Run Code Online (Sandbox Code Playgroud)
然后我在 http 处理程序函数中“没有这样的表”。
existed, err := db.GetAgentByServerName(agent.ServerName)
if err != nil {
c.JSON(http.StatusBadRequest, err)
log.Println("[conductor] error occurred when get agent by server name: " + err.Error())
return err
}
func GetAgentByServerName(name string) (*model.Agent, error) {
agent := &model.Agent{}
err := db.Get(agent, "select * from agent where ServerName=$1", name)
if err == sql.ErrNoRows {
err = nil
agent = nil
}
return agent, err
}
Run Code Online (Sandbox Code Playgroud)
当我启动程序时,我得到了
按服务器名称获取代理时发生错误:没有这样的表:代理
db 模式(省略属性)
var schema = `
DROP TABLE IF EXISTS agent;
CREATE TABLE agent (
Id INTEGER PRIMARY KEY,
);
DROP TABLE IF EXISTS task;
CREATE TABLE task (
Id INTEGER PRIMARY KEY,
);
Run Code Online (Sandbox Code Playgroud)
我无法共享所有代码,这里是重现相同错误的最小示例。
package main
import (
"github.com/jmoiron/sqlx"
_ "github.com/mattn/go-sqlite3"
"log"
)
var db *sqlx.DB
func init() {
db = sqlx.MustConnect("sqlite3", ":memory:")
db.Exec("CREATE TABLE agent (Id INTEGER PRIMARY KEY,);")
}
func main() {
_, err:=db.Exec("insert into agent values (1)")
if err!=nil{
log.Println(err)
}
}
Run Code Online (Sandbox Code Playgroud)
:memory:将为每个连接打开一个单独的数据库。file::memory:?cache=shared代替使用。
更新:我还使用上面的代码遇到了一些锁定问题,在我看来,在测试中使用:memory:with是一个更好的解决方案。db.DB().SetMaxOpenConns(1)
如果您使用与此处发布的相同的架构来创建表,则永远不会创建该表,因为该架构有语法错误,它应该是这样的
var schema = `
DROP TABLE IF EXISTS agent;
CREATE TABLE agent (
Id INTEGER PRIMARY KEY
);
DROP TABLE IF EXISTS task;
CREATE TABLE task (
Id INTEGER PRIMARY KEY
);
`
Run Code Online (Sandbox Code Playgroud)
我猜测您的代码与示例代码相同,因此在 init 函数中您跳过了错误检查db.Exec(schema)(您不应该对 中的任何函数执行此操作Go)。由于未检查错误并且执行架构时出现错误,因此永远不会创建表,但程序会继续,请更正您的架构并检查错误,然后重试。在你的 init 函数中试试这个:
_, err := db.Exec(schema)
if err != nil {
log.Fatal(err)
}
Run Code Online (Sandbox Code Playgroud)