Rewriting Queries to Avoid Transactions

of dat a if ot her client s are allowed t o change records in bet ween your sum m ary queries. This will m ake t he sum m aries inconsist ent . To prevent t hat from happening, lock t he t ables while youre using t hem . • Locking also can be useful for a set of queries where only t he last st at em ent is an updat e. I n t his case, t he earlier st at em ent s dont m ake any changes and t here is not hing t hat needs t o be rolled back should t he updat e fail.

15.9.5 Rewriting Queries to Avoid Transactions

Som et im es applicat ions use t ransact ions unnecessarily. Suppose you have a t able meeting t hat records m eet ing and convent ion inform at ion including t he num ber of t icket s left for each event , and t hat youre writ ing a Perl applicat ion cont aining a funct ion get_ticket t hat dispenses t icket s. One way t o im plem ent t he funct ion is t o check t he t icket count , decrem ent it if it s posit ive, and ret urn a st at us indicat ing whet her a t icket was available. To prevent m ult iple client s from at t em pt ing t o grab t he last t icket at t he sam e t im e, issue t he queries wit hin a t ransact ion: [2] [2] The transact_init and transact_finish functions are discussed in Recipe 15.5 . sub get_ticket { my dbh, meeting_id = _; my ref = transact_init dbh; my count = 0; eval { check the current ticket count count = dbh-selectrow_array SELECT tix_left FROM meeting WHERE meeting_id = ?, undef, meeting_id; if there are tickets left, decrement the count if count 0 { dbh-do UPDATE meeting SET tix_left = tix_left-1 WHERE meeting_id = ?, undef, meeting_id; } dbh-commit ; }; count = 0 if ; if an error occurred, no tix available transact_finish dbh, ref, ; return count 0 } The funct ion dispenses t icket s properly, but involves a cert ain am ount of unnecessary work. I t s possible t o do t he sam e t hing wit hout using a t ransact ion at all. Decrem ent t he t icket count only if t he count is great er t han zero, t hen check whet her t he st at em ent affect ed a row: sub get_ticket { my dbh, meeting_id = _; my count = dbh-do UPDATE meeting SET tix_left = tix_left-1 WHERE meeting_id = ? AND tix_left 0, undef, meeting_id; return count 0; } I n MySQL, t he row count ret urned by an UPDATE st at em ent indicat es t he num ber of rows changed. This m eans t hat if t here are no t icket s left for an event , t he UPDATE w ont change t he row and t he count will be zero. This m akes it easy t o det erm ine whet her a t icket is available using a single query rat her t han wit h t he m ult iple queries required by t he t ransact ional approach. The lesson here is t hat alt hough t ransact ions are im port ant and have t heir place, you m ay be able t o avoid t hem and end up wit h a fast er applicat ion as a result . The single-query solut ion is an exam ple of what t he MySQL Reference Manual refers t o as an at om ic operat ion. The m anual discusses t hese as an efficient alt ernat ive t o t ransact ions.

Chapter 16. Introduction to MySQL on the Web

Sect ion 16.1. I nt roduct ion Sect ion 16.2. Basic Web Page Generat ion Sect ion 16.3. Using Apache t o Run Web Script s Sect ion 16.4. Using Tom cat t o Run Web Script s Sect ion 16.5. Encoding Special Charact ers in Web Out put