Mam problem z SQLite rzuca klucz w mojej maszynie, gdy dzwonię do bazy danych pisać w tym samym czasie, co odczyt. Dzieje się tak, gdy różne metody próbują uzyskać dostęp do bazy danych w tym samym czasie.połączenie bazy danych sqlite golang
To co robię jest podobne do tego, co robi się w this thread, zaakceptowana odpowiedź wyjaśnia, w jaki sposób korzystać z transakcji bazy danych, aby uniknąć blokad bazy danych.
Oto niektóre z moich kodu:
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!")
Mylące jest to program istnieje po to wyprowadzanie:
database lock?
database is locked
Database storage complete!
2014/09/09 18:33:11 database is locked
exit status 1
Nie chcę mój program do zatrzymania na blokadę bazy danych, Chcę, aby przechowywał dane w pamięci i kontynuował działalność, dopóki baza danych nie zostanie odblokowana i będę mógł spróbować ponownie.
Czy istnieje jakiś standardowy sposób, w jaki mogę to osiągnąć, może kolejka lub struktura danych jakiegoś rodzaju, lub czy istnieje jakiś sposób rozwiązania problemu z bazą danych?
Dlaczego program kończy działanie po wyprowadzeniu Database storage complete!
?
Edit:
wierzę, że problem został rozwiązany, ale nie mogę być pewien. Używam goroutines i połączenia DB w pakiecie. Poprzednio każdy func w moim kodzie był inicjalizacją połączenia z bazą danych, kiedy został wywołany. Teraz mam "globalną" zmienną dla połączenia DB zdefiniowanego na górze pakietu i zainicjowaną przed rozpoczęciem jakichkolwiek procedur. Oto kod w pigułce:
var nDB *sql.DB
Później w głównej func ...
mypkg.InitDB()
go mypkg.RunDatabaseOperations()
mypkg.BeginHTTPWatcher(rtr)
InitDB()
jest zdefiniowana jako następujące:
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())
}
}
Więc RunDatabaseOperations
skanuje zasobów internetowych dla danych okresowo i zapisuje je w bazie danych, gdy następuje zmiana (raz na kilka sekund). BeginHTTPWatcher
nasłuchuje żądań HTTP, aby dane mogły być odczytywane z uruchomionego programu i przesyłane przez sieć do żądającego danych, niezależnie od tego, czy jest to żądanie lokalne czy zewnętrzne. Jeszcze nie miałem problemu.
'2014/09/09 18:33:11 baza danych jest zablokowana' wygląda jak 'log.Fatal (err)' praca. Czy możesz podać więcej informacji, aby zrobić próbną próbkę? Którego dostawcy sqlite używasz? – RoninDev
Używam 'github.com/mattn/go-sqlite3' – bvpx
Wydaje się, że problem współbieżności ... Czy uruchomiłeś ten kod równolegle? Jeśli tak, opublikuj więcej kodu, abyśmy mogli zobaczyć, co się dzieje. –