Sono due cose diverse, anche se connesse.
La transazione è 'indispensabile' nel momento in cui vado ad aggiornare i dati nella tabella.
Il lock pessimistico (quello che tu applichi con il lock della tabella) non è sempre la scelta migliore, e quindi non sempre raccomandato, soprattutto in uno scenario multi-utente.
L'esempio che tu hai fatto è mal posto, perchè se blocchi la tabella, nessun'altro utente potrà accedere ai dati del record, quindi non potrà sapere qual'è la disponibilità reale del prodotto.
Tieni presente che il lock pessimistico è vivamente sconsigliato per il semplice fatto che c'è il rischio reale che la tabella venga bloccata inutilmente, e a tempo indeterminabile (l'utente va al bagno, lo chiama il capo, riceve una telefonata urgente, e così via...).
Bloccare il record, in questi casi, rischia di creare blocco del sistema, aggiungendo il fatto che poi non si sa ancora cosa modifica l'utente (ammesso che modifichi davvero qualcosa).
Pensiamo, ad esempio, ad una banale registrazione via WEB di uno o più posti in un volo aereo da parte di più utenti.
In primis, in uno scenario come questo non è possibile bloccare la tabella, ma è chiaro che si deve prevedere un meccanismo di controllo sulla disponibilità effettiva al momento della registrazione da parte dell'utente, azione che spesso include più passaggi.
Ecco che allora diventa indispensabile racchiuderequesti passaggi all'interno di una transazione grazie alla quale se qualcosa va storto (disponibilità insufficiente, carta di credito sbagliata, ecc.) è possibile annullare tutto.
In generale si usa il lock ottimistico, tramite l'aiuto di un campo TimeStamp:
si confronta il TimeStamp che hai in canna, con quello che è sulla tabella :
1 - se i due TimeStamp coincidono, allora si apre la transazione e si aggiornano i dati.
2 - se i due TimeStamp NON coincidono, non devi aggiornare perchè significa che un'altro utente ha modificato i dati, ed è quindi necessario ricaricarli dalla tabella e poi potrai procedere di nuovo alla modifica degli stessi.