# Rails, mysql, ricerche e campi bloccati

**URL:** <https://www.ruby-forum.com/t/rails-mysql-ricerche-e-campi-bloccati/158093>\
**Category:** IT\
**Created:** [January 19, 2009, 10:57am UTC](https://www.ruby-forum.com/t/rails-mysql-ricerche-e-campi-bloccati/158093 "2009-01-19T10:57:34Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![daneel\_olivaw](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/58f4c7/32.png) [@daneel\_olivaw](https://www.ruby-forum.com/u/daneel_olivaw)\
**Post date:** [January 19, 2009, 10:57am UTC](https://www.ruby-forum.com/t/rails-mysql-ricerche-e-campi-bloccati/158093/1 "2009-01-19T10:57:34Z")

</div>

Buongiorno, signori.  
DovrÃ² realizzare un’applicazione per gestire l’agenda degli utenti da  
chiamare da un contact center (tutto legale, sono clienti da contattare  
prima che venga troppo tardi e chiamino tutti assieme gli ultimi 2  
giorni utili 🙂 ). L’ipotesi era di usare mysql e rails come  
interfaccia web, il funzionamento dovrÃ essere pressappoco cosÃ¬:  
l’operatore arriva, riceve le direttive su chi chiamare (clienti del tal  
paese, con le tali caratteristiche, ecc.), fa la ricerca, gli compare la  
lista, clicca su un nominativo, si apre la pagina con le caratteristiche  
(nome, cognome, numeri di telefono, ecc.), campi note, check vari  
(chiamato, a posto, non risposto, scassasfere, ecc.), effettua la  
chiamata, prende l’appuntamento se trova il tipo (su un’altra  
applicazione), scrive le note e quello che deve sul profilo cliente,  
salva, torna alla ricerca e via col prossimo.  
Primo problema: se un operatore apre il profilo di un utente, gli altri  
NON DEVONO essere in grado di fare la stessa cosa, in quanto Ã¨ giÃ in  
“elaborazione”; in teoria si risolve coi blocchi sui record di mysql…  
non li ho mai usati, ma me li guarderÃ². Se perÃ² qualcuno ha  
suggerimenti, consigli, pezzi di codice avanzato o altro, mi dica pure  
🙂  
Secondo problema: ho notato che quando si fa una ricerca con ruby, i  
dati dei campi trovati sono salvati nell’apposita variabile fino a che  
non viene rigenerata. Il problema Ã¨ che se lavora cosÃ¬ e due operatori  
fanno la stessa ricerca scegliendo entrambi “Pinco Pallino” (anche a  
differenza di qualche secondo, non per forza nel medesimo istante), in  
teoria entrambi dovrebbero ritrovarsi con la possibilitÃ di modificare  
l’utente, in quanto compare nella ricerca come non bloccato e potrebbero  
esserci problemi di sovrascritture o peggio… ho visto bene, oppure mi  
sono confuso?

Come sempre grazie in anticipo e a presto 🙂

---

<div class="post-metadata">

**Author:** ![daneel\_olivaw](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/58f4c7/32.png) [@daneel\_olivaw](https://www.ruby-forum.com/u/daneel_olivaw)\
**Post date:** [January 19, 2009, 11:22am UTC](https://www.ruby-forum.com/t/rails-mysql-ricerche-e-campi-bloccati/158093/2 "2009-01-19T11:22:46Z")

</div>

2009/1/19 Daneel O. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> Primo problema: se un operatore apre il profilo di un utente, gli altri  
> NON DEVONO essere in grado di fare la stessa cosa, in quanto è già in  
> “elaborazione”; in teoria si risolve coi blocchi sui record di mysql…

non potresti semplicemente aggiungere un campo boolean  
“in\_elaborazione”, oppure un campo id  
“utente\_che\_se\_ne\_sta\_occupando\_id”?

lo potresti settare quando l’utente clicca sul nome; se poi l’utente  
per qualche motivo lascia perdere (non so se implementi questa  
feature), ricambi il record, mettendo null nella colonna.

così resta ancora la possibilità teorica di concorrenza, ma è  
estremamente ridotta, e per meno di 100 utenti che lavorano  
contemporaneamente penso che difficilmente si  
verificherà.  
ciò non esclude l’uso di trucchetti mysql ma li rende meno indispensabili.

> Secondo problema: ho notato che quando si fa una ricerca con ruby, i  
> dati dei campi trovati sono salvati nell’apposita variabile fino a che  
> non viene rigenerata. Il problema è che se lavora così e due operatori  
> fanno la stessa ricerca scegliendo entrambi “Pinco Pallino” (anche a  
> differenza di qualche secondo, non per forza nel medesimo istante), in  
> teoria entrambi dovrebbero ritrovarsi con la possibilità di modificare  
> l’utente, in quanto compare nella ricerca come non bloccato e potrebbero  
> esserci problemi di sovrascritture o peggio… ho visto bene, oppure mi  
> sono confuso?

aspetta.  
se da applicazione web (ma anche da client mysql, a mano) fai una  
query, di solito non la rifai ogni secondo, ti accontenti di leggere i  
risultati. così, è inevitabile che una ricerca “invecchi”, anche solo  
dopo pochi secondi. questo problema, di per sé, è irrisolvibile.

però, se quando l’utente decide di fare qualcosa con un certo record  
tu cambi un valore del record stesso, come dicevo sopra, riduci il  
tempo in cui può avvenire un problema a pochissimi istanti (il tempo  
di un click, di solito molto meno di un secondo); sempre come sopra,  
puoi anche utilizzare i lock del db per eliminare anche questo  
rischio, che però, ribadisco, è quasi inesistente (di quanti  
telefonisti stiamo parlando?)

su come poi si faccia, in mysql, a fare questi lock, mi spiace, non so  
aiutarti.

---

<div class="post-metadata">

**Author:** ![daneel\_olivaw](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/58f4c7/32.png) [@daneel\_olivaw](https://www.ruby-forum.com/u/daneel_olivaw)\
**Post date:** [January 19, 2009, 11:43am UTC](https://www.ruby-forum.com/t/rails-mysql-ricerche-e-campi-bloccati/158093/3 "2009-01-19T11:43:40Z")

</div>

Pietro G. wrote:

> 2009/1/19 Daneel O. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):
> 
> > Primo problema: se un operatore apre il profilo di un utente, gli altri  
> > NON DEVONO essere in grado di fare la stessa cosa, in quanto ï¿½ giï¿½ in  
> > “elaborazione”; in teoria si risolve coi blocchi sui record di mysql…
> 
> non potresti semplicemente aggiungere un campo boolean  
> “in\_elaborazione”, oppure un campo id  
> “utente\_che\_se\_ne\_sta\_occupando\_id”?
> 
> lo potresti settare quando l’utente clicca sul nome; se poi l’utente  
> per qualche motivo lascia perdere (non so se implementi questa  
> feature), ricambi il record, mettendo null nella colonna.

E’ stata la prima ipotesi presa in considerazione, ma c’Ã¨ un problema:  
se l’utente mi chiude la pagina (o finestra), addio cambio di valore sul  
campo apposito, se invece si usano i controlli di mysql, in teoria  
dovrebbe sbloccarsi. Ricordo che per ora in pratica so solo che esistono  
e poco piÃ¹, quindi se dico scemate correggetemi 🙂

> > Secondo problema: ho notato che quando si fa una ricerca con ruby, i  
> > dati dei campi trovati sono salvati nell’apposita variabile fino a che  
> > non viene rigenerata. Il problema ï¿½ che se lavora cosï¿½ e due operatori  
> > fanno la stessa ricerca scegliendo entrambi “Pinco Pallino” (anche a  
> > differenza di qualche secondo, non per forza nel medesimo istante), in  
> > teoria entrambi dovrebbero ritrovarsi con la possibilitï¿½ di modificare  
> > l’utente, in quanto compare nella ricerca come non bloccato e potrebbero  
> > esserci problemi di sovrascritture o peggio… ho visto bene, oppure mi  
> > sono confuso?
> 
> aspetta.  
> se da applicazione web (ma anche da client mysql, a mano) fai una  
> query, di solito non la rifai ogni secondo, ti accontenti di leggere i  
> risultati. cosï¿½, ï¿½ inevitabile che una ricerca “invecchi”, anche solo  
> dopo pochi secondi. questo problema, di per sï¿½, ï¿½ irrisolvibile.

SÃ¬, questo lo so. Il mio dubbio Ã¨: se clicco su un utente della ricerca  
per aprire la maschera di modifica, i dati che vedo sono quelli  
“catturati” dalla ricerca (e quindi vecchi), oppure sono ricaricati dal  
database (e quindi belli freschi)?  
Ora che ci penso, potrei rifare una ricerca prima di visualizzare quel  
dato… faccio un passaggio in piÃ¹, ma sono piÃ¹ sicuro del dato non in  
elaborazione da qualcun altro.

> perï¿½, se quando l’utente decide di fare qualcosa con un certo record  
> tu cambi un valore del record stesso, come dicevo sopra, riduci il  
> tempo in cui puï¿½ avvenire un problema a pochissimi istanti (il tempo  
> di un click, di solito molto meno di un secondo); sempre come sopra,  
> puoi anche utilizzare i lock del db per eliminare anche questo  
> rischio, che perï¿½, ribadisco, ï¿½ quasi inesistente (di quanti  
> telefonisti stiamo parlando?)

I telefonisti saranno 5, niente di grosso, per fortuna… ah, se a  
qualcuno interessa, ben venga a darmi una mano… e se siete a  
conoscenza di qualcosa del genere giÃ in funzione, ditemi pure dove  
trovarla (per ora non ho visto niente che possa fare al caso nostro).

> su come poi si faccia, in mysql, a fare questi lock, mi spiace, non so  
> aiutarti.

VorrÃ dire che studierÃ² da solo… sperando di capirci qualcosa '🙂

---

<div class="post-metadata">

**Author:** ![daneel\_olivaw](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/58f4c7/32.png) [@daneel\_olivaw](https://www.ruby-forum.com/u/daneel_olivaw)\
**Post date:** [January 19, 2009, 11:50am UTC](https://www.ruby-forum.com/t/rails-mysql-ricerche-e-campi-bloccati/158093/4 "2009-01-19T11:50:21Z")

</div>

Il 19 gennaio 2009 11.43, Daneel O. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) ha  
scritto:

> E’ stata la prima ipotesi presa in considerazione, ma c’è un problema:  
> se l’utente mi chiude la pagina (o finestra), addio cambio di valore sul  
> campo apposito, se invece si usano i controlli di mysql, in teoria  
> dovrebbe sbloccarsi. Ricordo che per ora in pratica so solo che esistono  
> e poco più, quindi se dico scemate correggetemi 🙂  
> vero, non ci avevo pensato.

poiché continuo a non conoscere i meccanismi di lock, rilancio: dopo  
un’ora dal settaggio di un capo di tipo datetime, sblocchi il record.  
ma in effetti così diventa macchinoso.

> Sì, questo lo so. Il mio dubbio è: se clicco su un utente della ricerca  
> per aprire la maschera di modifica, i dati che vedo sono quelli  
> “catturati” dalla ricerca (e quindi vecchi), oppure sono ricaricati dal  
> database (e quindi belli freschi)?  
> Ora che ci penso, potrei rifare una ricerca prima di visualizzare quel  
> dato… faccio un passaggio in più, ma sono più sicuro del dato non in  
> elaborazione da qualcun altro.

se usi rails, non c’è problema: quando clicchi, viene effettuata una  
nuova request, e quindi rifatta la query (e anche se fosse  
un’applicazione desktop lo farei comunque, perché non puoi sapere,  
appunto, quanto tempo aspetterà un utente prima di cliccare su un  
link).

---

<div class="post-metadata">

**Author:** ![daneel\_olivaw](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/58f4c7/32.png) [@daneel\_olivaw](https://www.ruby-forum.com/u/daneel_olivaw)\
**Post date:** [February 9, 2009, 3:55pm UTC](https://www.ruby-forum.com/t/rails-mysql-ricerche-e-campi-bloccati/158093/5 "2009-02-09T15:55:11Z")

</div>

Pietro G. wrote:

> Il 19 gennaio 2009 11.43, Daneel O. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) ha  
> scritto:
> 
> > E’ stata la prima ipotesi presa in considerazione, ma c’ï¿½ un problema:  
> > se l’utente mi chiude la pagina (o finestra), addio cambio di valore sul  
> > campo apposito, se invece si usano i controlli di mysql, in teoria  
> > dovrebbe sbloccarsi. Ricordo che per ora in pratica so solo che esistono  
> > e poco piï¿½, quindi se dico scemate correggetemi 🙂  
> > vero, non ci avevo pensato.
> 
> poichï¿½ continuo a non conoscere i meccanismi di lock, rilancio: dopo  
> un’ora dal settaggio di un capo di tipo datetime, sblocchi il record.  
> ma in effetti cosï¿½ diventa macchinoso.

Riesumo la discussione perchÃ© potrebbe interessare altri e anche per  
vedere se ci sono eventuali alternative che qualcuno conosce.

Approfondendo ActiveRecord, ho visto che gestisce i lock, il problema Ã¨  
che lo fa solo nel momento di modificare i dati, con gli strumenti  
attuali non Ã¨ possibile fare in modo che blocchi il record quando  
l’utente lo richiama e lo sblocchi quando ha finito di lavorarci. Alla  
fine ho trovato che tutti hanno adottato la soluzione a cui eravamo  
giunti anche noi (io e il mio collega): tabellina in cui memorizzare  
id\_utente, id\_operatore e timestamp e verificare su questa qualki utenti  
da chiamare non comparissero bloccati. E’ una soluzione un po’ piÃ¹  
evoluta del semplice flag “bloccato” nel record dell’utente che permette  
di fare piazza pulita di eventuali “sessioni” rimaste bloccate causa  
uscita impropria dell’operatore grazie al timestamp: una ricerca di  
quelli piÃ¹ vecchi di un tot seguita da eliminazione e si Ã¨ a posto 🙂  
Uhm… si potrebbe mettere anche flag + timestamp direttamente sul  
record utente… vedrÃ² cosa Ã¨ meglio.

---

<div class="post-metadata">

**Author:** ![daneel\_olivaw](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/58f4c7/32.png) [@daneel\_olivaw](https://www.ruby-forum.com/u/daneel_olivaw)\
**Post date:** [February 10, 2009, 12:00pm UTC](https://www.ruby-forum.com/t/rails-mysql-ricerche-e-campi-bloccati/158093/6 "2009-02-10T12:00:18Z")

</div>

Ciao!  
Potresti postare la tua soluzione completa per risolvere questo problema  
della concorrenza sui campi, potrebbe essere utile a molti!

Grazie!  
Enrico

---

<div class="post-metadata">

**Author:** ![daneel\_olivaw](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/58f4c7/32.png) [@daneel\_olivaw](https://www.ruby-forum.com/u/daneel_olivaw)\
**Post date:** [February 10, 2009, 4:33pm UTC](https://www.ruby-forum.com/t/rails-mysql-ricerche-e-campi-bloccati/158093/7 "2009-02-10T16:33:04Z")

</div>

Enrico B. wrote:

> Ciao!  
> Potresti postare la tua soluzione completa per risolvere questo problema  
> della concorrenza sui campi, potrebbe essere utile a molti!
> 
> Grazie!  
> Enrico

Wow, che emossione, una richiesta diretta di vedere il codice per  
pubblica utilitÃ ! 🙂

Dopo la boiata, le cose utili.

Come lasciavo intendere, ho esaminato il caso e mi sono orientato per il  
sistema semplice, cioÃ¨ alla tabella coi dati da gestire ho aggiunto i  
campi “bloccato” e “datablocco”, rispettivamente booleano e datetime.

Nelle ricerche ho aggiunto come parametro discriminante anche il valore  
di “bloccato”, per cui ho qualcosa del genere:

class AgendaController \< ApplicationController  
codice codice…

def cerca  
…  
@contacts = Contact.find(:all, :from =\> “contacts”, :conditions =\>  
“[condizione1] and [condizione2] and bloccato=‘0’”)  
…  
end  
codice codice…

Passando alla gestione vera e propria dell’apertura dei dati con  
relativo blocco, acco qui che ho combinato:

def modifica  
@contact = Contact.find(params[:id]) #naturalmente qui ci si arriva  
dalla pagina “cerca” in cui come visto sopra saranno trovati solo i  
contatti non bloccati  
@contact.update\_attribute(:bloccato, ‘1’)  
@contact.update\_attribute(:datablocco, “#{Time.now}”)  
end

In questa maniera appena si carica la pagina si setta il blocco e si  
scrive la data in cui Ã¨ stato fatto. Quest’ultima servirÃ per sistemare  
le cose in caso l’operatore faccia un’uscita non gestita… sÃ¬, si  
potrebbe fare una ricerca per bloccato = 1, ma che succede se qualcuno  
ci sta lavorando? Gli resettiamo i dati sotto i piedi? Con la data si  
possono fare ricerche piÃ¹ mirate ed evitare macelli 🙂

Siamo quindi dentro la pagina di gestione dei dati, bene, ora abbiamo  
finito, si vuole salvare e “mollare” il record al resto del modo.  
Io ho messo i parametri dentro la pagina "modifica.html.erb (la view  
corrispondente, in pratica):  
…  
  
  
…

In questa maniera premendo l’apposito pulsante del form si  
“cancelleranno” i valori di blocco, permettendo agli altri di poter  
buttare all’aria tutto il nostro prezioso lavoro appena fatto 😃

Se a qualcuno interessa la gestione tramite una tabella separata, qui:  
[http://www.corprew.org/blog/2007/05/07/long-live-locks-part-1/](http://www.corprew.org/blog/2007/05/07/long-live-locks-part-1/) se ne  
parla un po’… peccato non ci sia la parte 2 dell’articolo, ma penso  
che non ci sia nulla di troppo astruso, tranne una gestione un po’ piÃ¹  
elaborata delle ricerche e dei salvataggi.

Spero di essere stato chiaro, in caso domandate se non mi sono spiegato  
bene… e se fate di meglio, ditemelo che scopiazzo 🙂

A presto.
