Laden...

Parallel mit zwei Thread auf eine SQLite-Datei zugreifen?

Erstellt von Thron vor 6 Jahren Letzter Beitrag vor 6 Jahren 1.885 Views
T
Thron Themenstarter:in
63 Beiträge seit 2017
vor 6 Jahren
Parallel mit zwei Thread auf eine SQLite-Datei zugreifen?

verwendetes Datenbanksystem: SQLite

Hallo,

habe ein Problem und komme nicht weiter. Ich schreibe verschiedene Datensätze in eine SQLite-Datei, die unabhängig voneinander sind. Deswegen würde ich gerne mit zwei Methoden jeweils zeitgleich Datensätze in die Datei schreiben bzw. lesen. Da die Methoden parallel laufen sollen wird jede in einen Thread gepackt.

Wen ich nun mein Programm starte schließt der eine Thread nach getaner Arbeit die DB-Connection zur SQLite-Datei und ich bekomme die Fehlermeldung:


System.InvalidOperationException: "Connection was closed, 
statement was terminated"

Kann ich irgendnwie parallel auf die SQLite-Datei zugreifen? Habe schon versucht zwei SQLiteConnection Objekte zu erstellen, geht aber irgendwie auch nicht!?

Viele Dank für Eure Ideen und Mühen schon im Voraus...

Gruß

16.834 Beiträge seit 2008
vor 6 Jahren

Die SQLiteConnection ist nicht Thread-Safe, das sollte auch in der Dokumentation stehen. Keine ADO.NET Connection ist Thread-Safe, egal ob Oracle, SqlServer oder Sqlite.
Jeder Thread braucht seine eigene SQLiteConnection, dann klappt das auch.

"Geht nicht" ist keine Fehlermeldung, mit der wir was anfangen können.

T
Thron Themenstarter:in
63 Beiträge seit 2017
vor 6 Jahren

okay....dass verstehe ich.

Ich habe versucht zwei Connections zu erstellen:


        string DataSource = "daten.sqlite";

        SQLiteConnection connection;
        SQLiteConnection connection1;


        private void OpenConnection()
        {
            connection = new SQLiteConnection();
            connection.ConnectionString = "Data Source=" + DataSource;
            connection.Open();
        }

        private void OpenConnection1()
        {
            connection1 = new SQLiteConnection();
            connection1.ConnectionString = "Data Source=" + DataSource;
            connection1.Open();
        }



        private void CloseConnection()
        {
            connection.Close();
            connection.Dispose();
        }

        private void CloseConnection1()
        {
            connection1.Close();
            connection1.Dispose();
        }

Starte dann die Methode 1 mit eine Thread und in der Methode öffne und schließe ich die Verbindung mit:


            OpenConnection();
            CloseConnection();

und die Methode2 mit eine anderen Thread mit:


            OpenConnection1();
            CloseConnection1();

Dann bekomme ich zwei Exceptions, immer dass auf das verworfene Objekt nicht mehr zugegriffen werden kann.

Wie würden denn sowas aussehen mit zwei SQLConnects un den Thread dazu...Irgendwo ist mein Fehler, kann ja aber nicht den ganzen Code Posten..

T
Thron Themenstarter:in
63 Beiträge seit 2017
vor 6 Jahren

Habe den Fehler gefunden....!!!

Habe jetzt korrekte Connections erstellt und jetzt geht es....

Viele Dank trotzdem...

T
2.224 Beiträge seit 2008
vor 6 Jahren

Deine Methoden sehen mir sehr nach static bzw. gehaltene Connection in einem Instanz Objekt.
Du solltest deine Connection öffnen, deine Abfrage senden und dann die Connection schließen.
Connections sollten nur für Abfragen kurz geöffnet und danach wieder geschlossen werden.
Wenn du weitere braucht, dann leg dir neue Connection Objekte an.

Schau dir dazu auch das Thema Connection Pooling an.
Kann man ggf. auch im Connection String für Sqlite mitgeben.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

2.298 Beiträge seit 2010
vor 6 Jahren

@Thron,

sieh dir zu ADO.NET vielleicht auch mal DatenbankClient ADO.NET - Providerunabhängig an. Die Klasse kannst du 1 zu 1 übernehmen. Das hat den Charme, dass du anschließend nicht mehr manuell mit den Connections spielen musst.

Alles was du zu tun hast, ist eine Instanz des DbClient zu erstellen und anschließend deine Abfragen ausführen.

Deine Datenabfragen kannst du dann mit Hilfe der Methoden: *ExecuteDataSet, *ExecuteDataReader, *ExecuteScalar und *ExecuteNonQuery

ausführen.

Wichtig ist jedoch, dass auch der DBClient nicht Threadsicher ist und du für die parallelen Abfragen 2 Instanzen brauchst.

In deinem Fall wäre die korrekte Initialisierung wohl:


DbClient dbClient = new DbClient("System.Data.SQLite", "Data Source=daten.sqlite;");

Das alles aber nur als Tipp und Hilfestellung.

Wissen ist nicht alles. Man muss es auch anwenden können.

PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager |