Datenbank Frage zu asynchronen Zugriffen

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
Xbash_Zero
User
Beiträge: 30
Registriert: Montag 19. September 2022, 22:48

Hallo,

ich beschäftige mich seit etwa einem Jahr mit der Programmierung, vor allem mit der Sprache Python und hätte hier eine Frage, die ich hier gerne stellen möchte.

Es geht um folgendes, ich arbeite an einem Programm, bei dem es vorkommen kann, dass gleichzeitige Zugriffe auf eine MYSQL Datenbank stattfinden. Wie könnte man verhindern, dass es zu Fehlern oder Inkonsistenzen bei den Daten kommt, falls der Fall eines gleichzeitigen Zugriffs erfolgt?

Ich hatte mir etwas überlegt, mein Ansatz wäre eine Warteschlange, die ich in etwa so gebaut hätte, siehe Code. Es würde mich freuen, wenn ihr mir sagen könntet, ob man das so machen könnte, ob das thread safe ist und ob es bessere Möglichkeiten gäbe? Danke im Voraus...

Code: Alles auswählen

import queue
import threading
import mysql.connector

# Verbindung zur MySQL-Datenbank herstellen
db = mysql.connector.connect(
  host="192.168.102.17",
  user="root",
  password="...",
  database="test"
)

#print(db)

# Lock erstellen
lock = threading.Lock()

# Queue erstellen
q = queue.Queue()

# Funktion zum Ausführen von MySQL-Abfragen
def run_query(query):
    cursor = db.cursor()
    cursor.execute(query)
    result = cursor.fetchall()
    cursor.close()
    return result

# Funktion zum Ausführen der Warteschlange
def process_queue():
    while True:
        # MySQL-Abfrage aus der Warteschlange abrufen
        query = q.get()

        # Lock acquiren
        lock.acquire()

        # MySQL-Abfrage ausführen
        print(run_query(query))

        # Lock releasen
        lock.release()

        # Abgeschlossene Abfrage aus der Warteschlange entfernen
        q.task_done()

# Beispiel-Abfragen zur Warteschlange hinzufügen
#q.put("INSERT INTO my_table (column1, column2) VALUES ('value1', 'value2')")
q.put("SELECT * FROM tab_test")

# Threads erstellen und starten
for i in range(4):
    t = threading.Thread(target=process_queue)
    t.daemon = True
    t.start()

# Warten, bis die Warteschlange abgeschlossen ist
q.join()

# Verbindung zur MySQL-Datenbank schließen
db.close()
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das macht man üblicherweise nicht, weil es sehr restriktiv ist. Vor allem bei deinem Ansatz bringen die Threads ja gar nichts, weil sie eh serialisiert sind. Da kannst du auch nur einen starten.

Stattdessen benutzt man die Transaktionsgarantien der Datenbank, und ggf. deren eigens, fein-granulareres Locking.
Xbash_Zero
User
Beiträge: 30
Registriert: Montag 19. September 2022, 22:48

__deets__ hat geschrieben: Freitag 17. Februar 2023, 17:00 Das macht man üblicherweise nicht, weil es sehr restriktiv ist. Vor allem bei deinem Ansatz bringen die Threads ja gar nichts, weil sie eh serialisiert sind. Da kannst du auch nur einen starten.

Stattdessen benutzt man die Transaktionsgarantien der Datenbank, und ggf. deren eigens, fein-granulareres Locking.
Was bedeutet "Transaktionsgarantien der Datenbank"? Meinst du so etwas wie MyISAM, was direkt von der DB-Engine kommt?
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ich meine sowas hier: https://www.postgresql.org/docs/current ... n-iso.html

Das wird es auch fuer MySQL geben. Nehme ich mal an, ich arbeite damit nicht. Aber damit regelt die Datenbank, was eine Transaktion zu sehen bekommt. Du kannst also je nach Zweck das Isolationslevel benutzen, dass fuer deine Anwendung richtig ist. Denn dein Problem hier ist ja eh nur halb durchdacht: das man nur *einen* Prozess hat, in dem man die Aenderungen der Datenbank vornimmt, ist ein ungewoehnliche und harte Einschraenkung. Wer zB eine Webanwendung baut, oder jede andere Anwendung, die wirklich einen DB-Server braucht (und nicht mit SQLite zufrieden ist), will ja moeglichst mehrere Verbindungen, die Daten veraendern koennen.
Benutzeravatar
sparrow
User
Beiträge: 4195
Registriert: Freitag 17. April 2009, 10:28

Achtung gefährliches Halbwissen: MyISAM kann meines Wissens keine Transaktionen. INNODB wohl schon. So war es füher.
Antworten