Tôi đang gặp rắc rối với SQLite ném một cờ lê trong máy móc của tôi khi tôi gọi cơ sở dữ liệu viết vào cùng thời điểm chính xác như đã đọc. Điều này xảy ra khi các phương pháp khác nhau xảy ra để cố gắng truy cập cơ sở dữ liệu tại cùng một thời điểm chính xác.golang kết nối cơ sở dữ liệu sqlite pooling
Điều tôi đang làm tương tự với những gì đang được thực hiện trong this thread, câu trả lời được chấp nhận giải thích cách sử dụng các giao dịch cơ sở dữ liệu để tránh các khóa cơ sở dữ liệu.
Dưới đây là một số mã của tôi:
stmt, err := dbtx.Prepare(`statement`)
if err != nil {
log.Fatal(err)
}
_, err = stmt.Exec(values, values, values)
if err != nil {
log.Fatal(err)
}
err = dbtx.Commit()
if err != nil {
fmt.Println("database lock?")
fmt.Println(err)
dbtx.Rollback()
}
fmt.Println("Database storage complete!")
Điều khó hiểu là chương trình tồn tại sau khi xuất ra này:
database lock?
database is locked
Database storage complete!
2014/09/09 18:33:11 database is locked
exit status 1
Tôi không muốn chương trình của tôi để ngăn chặn trên một khóa cơ sở dữ liệu, Tôi muốn nó lưu trữ dữ liệu trong bộ nhớ và tiếp tục kinh doanh cho đến khi cơ sở dữ liệu được mở khóa và tôi có thể thử lại.
Có cách nào tiêu chuẩn tôi có thể đạt được điều này, có thể là một hàng đợi hoặc cấu trúc dữ liệu của một số loại hoặc có cách cụ thể về cơ sở dữ liệu để giải quyết vấn đề này?
Tại sao chương trình thoát sau khi xuất ra Database storage complete!
?
Edit:
Tôi tin rằng tôi đã khắc phục các vấn đề, nhưng tôi không thể chắc chắn. Tôi đang sử dụng goroutines và một kết nối DB trọn gói. Trước đây, mỗi func trong mã của tôi đã khởi tạo một kết nối cơ sở dữ liệu khi nó được gọi. Bây giờ, tôi có một biến "toàn cầu" cho kết nối DB được định nghĩa ở đầu gói và được khởi tạo trước khi bất kỳ thường trình nào bắt đầu. Dưới đây là mã trong một nutshell:
var nDB *sql.DB
Sau đó trong func chính ...
mypkg.InitDB()
go mypkg.RunDatabaseOperations()
mypkg.BeginHTTPWatcher(rtr)
InitDB()
được định nghĩa như sau:
func InitDB() {
fmt.Println("Init DB ...")
var err error
nDB, err = sql.Open("sqlite3", "./first.db")
if err != nil {
log.Fatal(err)
}
if nDB == nil {
log.Fatal(err)
}
fmt.Printf("nDB: %v\n", ODB)
fmt.Println("testing db connection...")
err2 := nDB.Ping()
if err2 != nil {
log.Fatalf("Error on opening database connection: %s", err2.Error())
}
}
Vì vậy, RunDatabaseOperations
quét tài nguyên trực tuyến cho dữ liệu định kỳ và lưu trữ nó vào cơ sở dữ liệu khi có thay đổi (cứ sau vài giây). BeginHTTPWatcher
lắng nghe các yêu cầu HTTP để dữ liệu có thể được đọc từ chương trình đang chạy và truyền qua dây tới người yêu cầu dữ liệu, cho dù đó là yêu cầu địa phương hay bên ngoài. Tôi chưa có vấn đề gì.
'2014/09/09 18:33:11 cơ sở dữ liệu bị khóa' trông giống như công việc' log.Fatal (err) '. Bạn có thể cung cấp thêm thông tin, để làm mẫu thử không? Nhà cung cấp sqlite nào bạn sử dụng? – RoninDev
Tôi đang sử dụng 'github.com/mattn/go-sqlite3' – bvpx
Có vẻ như vấn đề đồng thời ... bạn có đang chạy mã này đồng thời không? Nếu có, vui lòng đăng thêm mã của bạn để chúng tôi có thể xem điều gì đang diễn ra. –