[Risolto][Python]MySQL + Threads non mi legge il valore

Linguaggi di programmazione: php, perl, python, C, bash e tutti gli altri.
TommyB1992
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 852
Iscrizione: domenica 7 luglio 2013, 15:55
Desktop: GNU/Linux
Distribuzione: Ubuntu 22.04.2 LTS
Sesso: Maschile

[Risolto][Python]MySQL + Threads non mi legge il valore

Messaggio da TommyB1992 »

File 1)

Codice: Seleziona tutto

Thread(target=genMenu).start()

def genMenu():
    conn = MariaDB()
    conn.main()

    while True:
        conn.exec("""
            SELECT 1
              FROM `tableMenu`
             WHERE `hwnd` = '%(hwnd)s'
             LIMIT 1
        """, {"hwnd", hwnd})

        print(conn.count())

        sleep(2)
File 2)

Codice: Seleziona tutto

conn.exec(
    "REPLACE INTO `tableMenu` VALUES ('%(hwnd)s')",
    {"hwnd", hwnd}
)
Funzioni database:
https://pastebin.com/ub5NZdA4


Ho due file, uno che inserisce un valore, il secondo che dovrebbe estrarrlo, ma non lo fa...

Ho cercato e su stackoverflow ho letto che ogni thread deve avere la sua connessione e qualche errore è stato risolto (prima non leggeva neanche i risultati che aggiornava dal suo stesso thread).

Il valore viene inserito correttamente perchè controllo su MariaDB, però non viene letto, ho pensato che potrei chiudere/aprire la connessione ad ogni query, però non mi sembra la soluzione ottimale e non so neanche se potrebbe funzionare...
Ultima modifica di TommyB1992 il mercoledì 15 novembre 2017, 23:10, modificato 1 volta in totale.
Avatar utente
toro2k
Prode Principiante
Messaggi: 148
Iscrizione: lunedì 30 gennaio 2012, 12:56
Località: Savona

Re: [Python]MySQL + Threads non mi legge il valore aggiornat

Messaggio da toro2k »

Difficile darti una mano con le informazioni che fornisci. Per risolvere il problema penso che potrebbe esserti d'aiuto preparare uno "short, self contained, correct/compilable example", alias "minimal, complete, verifiable example". :)
Software is meant to be soft!
TommyB1992
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 852
Iscrizione: domenica 7 luglio 2013, 15:55
Desktop: GNU/Linux
Distribuzione: Ubuntu 22.04.2 LTS
Sesso: Maschile

Re: [Python]MySQL + Threads non mi legge il valore aggiornat

Messaggio da TommyB1992 »

Seguendo "short, self contained, correct/compilable example" e"minimal, complete, verifiable example", ecco qua:

first.py

Codice: Seleziona tutto

from time import sleep
from threading import Thread

from Database import MariaDB


def test():
    conn = MariaDB()
    conn.main()

    while True:
        conn.exec("SELECT * FROM `tableMenu`")
        print(conn.fetch())
        sleep(2)
    ## End while
## End def test


Thread(target=test).start()
second.py

Codice: Seleziona tutto

from time import sleep, time

from Database import MariaDB

conn = MariaDB()
conn.main()

while True:
    v =  time()
    conn.exec(
        "INSERT INTO `tableMenu` VALUES ('%(hwnd)s')", {"hwnd": v}
    )
    print("Inserito: {}".format(v))
    sleep(2)
Andiamo da terminale (nel mio caso prompt dei comandi :( ):
python first.py

Apriamo altro terminale:
python second.py

Stdout di second.py:
C:\Users\tomas\Desktop\Test>python second.py
Inserito: 1510752297.64766
Inserito: 1510752299.650774
Inserito: 1510752301.652889
Inserito: 1510752311.99648

Stdout di first.pyt (aperto in contemporanea):
C:\Users\tomas\Desktop\Test>python first.py
[]
[]
[]


Una soluzione? Come immaginavo aprire/chiudere la connessione nel thread, però non mi piace come soluzione.
TommyB1992
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 852
Iscrizione: domenica 7 luglio 2013, 15:55
Desktop: GNU/Linux
Distribuzione: Ubuntu 22.04.2 LTS
Sesso: Maschile

Re: [Python]MySQL + Threads non mi legge il valore aggiornat

Messaggio da TommyB1992 »

Da un altro forum...
@riko
Allora, con l'esempio minimale, chiarissimo, un sospetto mi e' venuto.

Questo apparentemente sembra un classico problema di data isolation. Ovvero, chi legge non trova il dato che tu ti saresti aspettato che trovasse.
Il motivo e' che tipicamente per essere completamente ACID si paga un costo elevato. Quindi la maggior parte dei DB di fatto usano livelli di isolation piu' bassi che normalmente funzionano molto bene, ma quando vai a controllare nello specifico si manifestano grosso modo in questo modo. Il fatto che riaprendo la connessione il problema si risolve e' consistente con questo: riaprendo la connessione di fatto vedi l'ultimo stato salvato, inclusa la modifica.

Ora io non posso essere davvero che sia questo. Puoi cambiare i parametri di isolation per forzare il massimo e a quel punto dovrebbe funzionare tutto.

Un altra possibilita' e' che semplicemente le operazioni invocate non vengono completate prima che l'altro legga. Nel senso che tu stai guardando i log da Python, quindi vedi quello che ti dice il db, non quello che fa il DB. E' interamente possibile che quando fai session execute per scrivere tu debba in qualche modo fare commit (implicito alla chiusura). Essenzialmente questo e' vero anche nel caso in cui ci sono transazioni. Molti db invocano di default (oppure perche' configurati cosi') i comandi che gli dai dentro una transazione implicita, quindi devi committare la transazione (molti db hanno il comando COMMIT). Quando chiudi la connessione, la transazione e' automaticamente committata (o rollbackata se in errore). Si, ovviamente in questo caso sei comunque legato alla questione isolation... sarebbe una lunga discussione, ma le transazioni sono uno strumento prezioso nel campo della data isolation.

Non ho voglia di andare a vedere la documentazione di Maria DB, questi sono problemi che ho visto con altri db che si manifestano in modo simile. Hai anche abbastanza informazione per ingegnarti e capire come determinare se e' una delle due (che so... o leggendo la documentazione con quest'ottica in mente oppure facendo esperimenti -- no, provare a tirare comandi a caso non conta come esperimento... anche se e' possibile che aggiungendo COMMIT nel posto giusto risolvi davvero).

Esatto.

Ho letto io la documentazione per te, e MariaDB effettua le SELECT in modalità UNCOMMITED.

Tanto di cappello, si risolve sia:
SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;

Da root o committando dopo la query.

I miei complimenti.
Avatar utente
toro2k
Prode Principiante
Messaggi: 148
Iscrizione: lunedì 30 gennaio 2012, 12:56
Località: Savona

Re: [Risolto][Python]MySQL + Threads non mi legge il valore

Messaggio da toro2k »

Sono contento che preparare un esempio come si deve ti sia stato d'aiuto! :)
Software is meant to be soft!
Scrivi risposta

Ritorna a “Programmazione”

Chi c’è in linea

Visualizzano questa sezione: Bing [Bot], Google [Bot] e 9 ospiti