2012-12-29 25 views
5

Realizzo un servizio Web in PHP che esegue una serie di calcoli basati su una selezione da una tabella e quindi aggiorna la tabella in seguito con i nuovi risultati.Blocco tabella MySql in PHP

Tuttavia, voglio impedire il caso in cui un'altra persona sta effettuando una chiamata allo stesso servizio web mentre la sessione di un'altra persona sta ancora facendo un aggiornamento.

È la cosa giusta qui bloccare l'intero tavolo e quindi sbloccarlo di nuovo? In tal caso, come posso bloccare e sbloccare una tabella mysql usando PHP pdo?

+0

Non è una risposta diretta, ma non penso che questo sia un problema. I calcoli e il recupero dei dati dal database vengono eseguiti in pochi millisecondi. Le probabilità o due persone che interagiscono allo stesso tempo sono così piccole che la maggior parte delle persone non si preoccupa di fare una serratura come questa. – OptimusCrime

+0

Lo realizzo. Tuttavia, non sono disposto a correre rischi in quanto la corruzione dei dati potrebbe avere gravi conseguenze per la mia applicazione. – user1574041

+0

Si desidera utilizzare [transazioni database] (http://dev.mysql.com/doc/en/sql-syntax-transactions.html), per garantire l'atomicità delle operazioni. – eggyal

risposta

0

ho pubblicato un commento:

Non è una risposta diretta, ma non credo che questo sia alcun problema. I calcoli e il recupero dei dati dal database vengono eseguiti entro pochi millisecondi . Le probabilità o le due persone che interagiscono allo stesso tempo sono così piccole che la maggior parte delle persone non si preoccupa di fare una serratura come questa.

Ma se questi calcoli sono fondamentali si potrebbe evitare questo problema aggiungendo un nuovo campo e semplicemente lo chiamano occupied, busy o qualcosa del genere.

Quando si esegue lo script, verificare se questo campo è impostato su ad esempio 1, se lo è, rendere lo script inattivo per 1-2-3 secondi e riprovare. Se questo campo è impostato su 0, aggiornarlo su 1, eseguire i calcoli e reimpostarlo nuovamente su 0.

Ciò impedirebbe a due persone di accedere agli stessi valori allo stesso tempo.

+0

Il problema con questo approccio è che se entrambi i client leggono il valore del campo di controllo prima che lo abbiano aggiornato, entrambi penseranno che possono procedere. Uno ha bisogno della CPU per eseguire operazioni * atomicamente * al fine di garantire la sicurezza nelle applicazioni concorrenti: i sistemi operativi forniscono un'API per questo, e l'RDBMS chiama quell'API nell'implementazione dei suoi meccanismi di blocco. ** Non provare a crearlo da solo ** dato che è destinato a fallire. Invece, usa l'atomicità fornita dalle transazioni del database: è ciò per cui sono lì. – eggyal

+0

Sembra la soluzione più sicura da implementare. Sono disposto a seguire questa strada. Sarebbe possibile trovare una soluzione per evitare che il caso eggyal venga menzionato? – user1574041

+0

@eggyal: Leggi l'altra risposta pubblicata qui. Non è possibile che due persone accedano allo stesso tempo. È fatto troppo velocemente perché ciò accada. – OptimusCrime

3

Gestione dei database I sistemi come MySQL sono abbastanza intelligenti da impedire violazioni della concorrenza come queste.

Cercare i livelli di isolamento del database (lettura non vincolata, lettura commessa, lettura ripetibile, serializzabile) e gli eventuali problemi (lettura sporca, lettura non ripetibile ...) ->Wikipedia.

Personalmente, non consiglierei un blocco da tavolo nel tuo caso. È meglio che lo avvolga i tuoi calcoli e le operazioni del database in una transazione e faccia affidamento sul DBMS per gestire i tuoi contenuti.

+0

Comunque lo sto facendo al momento: 1) Effettua una selezione sul mio tavolo 2) Effettua i miei calcoli in PHP in base a quello selezionato 3) Aggiorna la tabella in base ai calcoli PHP. È possibile nella transazione? Sono relativamente nuovo ai database. – user1574041

+1

@ user1574041: È possibile utilizzare [lettura bloccata] (http://dev.mysql.com/doc/en/innodb-locking-reads.html) come "SELEZIONA ... PER AGGIORNAMENTO". Tuttavia, potresti anche scoprire che puoi trasferire la tua logica di calcolo da PHP a SQL, in modo tale che venga eseguita in una singola istruzione "UPDATE", ad es. 'UPDATE myTable SET myColumn = (1 + myColumn) * 2 DOVE ...'. – eggyal

+0

Grazie a @eggyal, sarebbe anche la mia raccomandazione. Se decidi di dover eseguire i calcoli in php e non vuoi bloccare l'intera tabella, potresti voler guardare un meccanismo di blocco della base file come 'flock': http://php.net/manual/en/ function.flock.php –