La domanda è, se due utenti diversi voti simultaneamente la sua possibile che le due istanze del codice tenta di inserire un nuovo ID (o qualche simile tipo di query) che darà un erro
Sì, si potrebbe finire con due query facendo l'inserto. A seconda dei vincoli sulla tabella, uno di questi genererà un errore o finirai con due righe nel tuo database.
Si potrebbe risolvere questo, credo, con l'applicazione di un blocco; ad es.se è necessario aggiungere un voto al prodotto con id theProductId: (pseudo codice)
START TRANSACTION;
//lock on the row for our product id (assumes the product really exists)
select 1 from products where id=theProductId for update;
//assume the vote exist, and increment the no.of votes
update votes set numberOfVotes = numberOfVotes + 1 where productId=theProductId ;
//if the last update didn't affect any rows, the row didn't exist
if(rowsAffected == 0)
insert into votes(numberOfVotes,productId) values(1,theProductId)
//insert the new vote in the per user votes
insert into user_votes(productId,userId) values(theProductId,theUserId);
COMMIT;
qualche info in più here
MySQL offre un'altra soluzione pure, che potrebbe essere applicabile qui, insert on duplicate
es si potrebbe essere in grado di fare proprio:
insert into votes(numberOfVotes,productId) values(1,theProductId) on duplicate key
update numberOfVotes = numberOfVotes + 1;
Se i voti della tabella hanno una chiave univoca per la colonna del prodotto id, quanto sopra sarà fare un inserto se il particolare theProductId non esiste, altrimenti si farà un aggiornamento, dove incrementa la colonna numberOfVotes di 1
Probabilmente si potrebbe evitare molto questo se si creava una riga nella tabella dei voti nello stesso momento in cui si aggiungeva il prodotto al database. In questo modo puoi essere sicuro che c'è sempre una riga per il tuo prodotto e basta emettere un AGGIORNAMENTO su quella riga.
Potrebbe essere utile mostrare la struttura della tabella (nomi tabella/colonna) – rojoca
Sto solo dando un esempio ma per aiutarti: la tabella product_votes ha un productID, un votes_count e una total_votes_value column. La tabella user_product_votes ha un ID utente, un productID e una colonna user_vote. – Jonathan
L'unica ragione che chiedo è che in questo esempio sembra che sarebbe meglio riorganizzare la logica e la struttura della tabella in modo che gli inserimenti simultanei non contengano invece di cercando di prevenirli. Stai facendo una domanda generale o hai bisogno di risolvere il problema specifico nel tuo esempio? – rojoca