<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML><HEAD> <META content="text/html; charset=iso-8859-1" http-equiv=Content-Type> <META name=GENERATOR content="MSHTML 8.00.6001.18876"> <STYLE></STYLE> </HEAD> <BODY background="" bgColor=#ffffff> <DIV><FONT size=2 face=Courier>Pabandziau - tokie rezultatai.<BR><BR>Visu pirma paskaiciau dokumentacija http://msdn.microsoft.com/en-us/library/ms187373.aspx<BR><BR>ROWLOCK <BR><BR>Specifies that row locks are taken when page or table locks are ordinarily taken. When specified in transactions operating at the SNAPSHOT isolation level, row locks are not taken unless ROWLOCK is combined with other table hints that require locks, such as UPDLOCK and HOLDLOCK.<BR><BR>HOLDLOCK <BR>Is equivalent to SERIALIZABLE. For more information, see SERIALIZABLE later in this topic. HOLDLOCK applies only to the table or view for which it is specified and only for the duration of the transaction defined by the statement that it is used in. HOLDLOCK cannot be used in a SELECT statement that includes the FOR BROWSE option.<BR><BR>SERIALIZABLE <BR>Is equivalent to HOLDLOCK. Makes shared locks more restrictive by holding them until a transaction is completed, instead of releasing the shared lock as soon as the required table or data page is no longer needed, whether the transaction has been completed or not. The scan is performed with the same semantics as a transaction running at the SERIALIZABLE isolation level. For more information about isolation levels, see SET TRANSACTION ISOLATION LEVEL (Transact-SQL).<BR><BR>Isvadas padariau tokias, kad ROWLOCK hintas tiesiog sako "jei gali lockink tik irasa, bet ne page'a ir ne visa lenta". HOLDLOCK sako "sitas update sakinys turi vykti taip kaip lygtai tai butu serializable transakcija"<BR><BR>Tai iliustruoja labai paprastas pavyzdys:<BR>sukuriau tokia lentele my_table<BR>id user_id<BR>----------- ----------<BR>1 NULL<BR>2 NULL<BR>3 NULL<BR>4 NULL<BR>5 NULL<BR><BR>prasukau toki koda<BR><BR>begin tran<BR>set transaction isolation level read uncommitted<BR>update my_table with (rowlock) set user_id = 'aaa'<BR>where id = (select min(id) from my_table where user_id is null)<BR>exec sp_lock<BR>rollback tran<BR><BR>rezultatas<BR><BR>(1 row(s) affected)<BR>spid dbid ObjId IndId Type Resource Mode Status<BR>------ ------ ----------- ------ ---- -------------------------------- -------- ------<BR>52 5 0 0 DB S GRANT<BR>52 5 2089058478 0 PAG 1:114 IX GRANT<BR>52 5 2089058478 0 RID 1:114:0 X GRANT<BR>52 1 1115151018 0 TAB IS GRANT<BR>52 5 2089058478 0 TAB IX GRANT<BR><BR>nors sp_lock paleidziamas po update sakinio, galima matyt, kad irasas turi (RID 1:114:0) exclusive locka ir data page'as (PAG 1:114) turi intent exclusive locka, taip pat kaip ir visa lentele. Taigi teiginys, kad lockas releasinamas is karto po update sakinio yra klaidingas.</FONT></DIV> <DIV><FONT size=2 face=Courier></FONT> </DIV> <DIV><FONT size=2 face=Courier>Jei panaudoti dar ir HOLDLOCK </FONT></DIV> <DIV><FONT size=2 face=Courier></FONT> </DIV> <DIV><FONT size=2 face=Courier>begin tran<BR>set transaction isolation level read uncommitted<BR>update my_table with (rowlock, holdlock) set user_id = 'aaa'<BR>where id = (select min(id) from my_table where user_id is null)<BR>exec sp_lock<BR>rollback tran</FONT></DIV> <DIV><FONT size=2 face=Courier></FONT> </DIV> <DIV><FONT size=2 face=Courier>gaunasi</FONT></DIV> <DIV><FONT size=2 face=Courier></FONT> </DIV> <DIV><FONT size=2 face=Courier>(1 row(s) affected)<BR>spid dbid ObjId IndId Type Resource Mode Status<BR>------ ------ ----------- ------ ---- -------------------------------- -------- ------<BR>52 5 0 0 DB S GRANT<BR>52 1 1115151018 0 TAB IS GRANT<BR>52 5 2089058478 0 TAB X GRANT</FONT></DIV> <DIV><FONT size=2 face=Courier></FONT> </DIV> <DIV><FONT size=2 face=Courier>t.y. ROWLOCK hintas is viso yra ignoruojamas ir visa lenta gauna X locka (ObjId = 2089058478)</FONT></DIV> <DIV><FONT size=2 face=Courier></FONT> </DIV> <DIV><FONT size=2 face=Courier>dabar jei vietoj HOLDLOCK, panaudot serializable transakcija</FONT></DIV> <DIV><FONT size=2 face=Courier></FONT> </DIV> <DIV><FONT size=2 face=Courier>begin tran<BR>set transaction isolation level serializable<BR>update my_table with (rowlock) set user_id = 'aaa'<BR>where id = (select min(id) from my_table where user_id is null)<BR>exec sp_lock<BR>rollback tran</FONT></DIV> <DIV><FONT size=2 face=Courier></FONT> </DIV> <DIV><FONT size=2 face=Courier>gaunasi stai kas</FONT></DIV> <DIV><FONT size=2 face=Courier></FONT> </DIV> <DIV><FONT size=2 face=Courier>(1 row(s) affected)<BR>spid dbid ObjId IndId Type Resource Mode Status<BR>------ ------ ----------- ------ ---- -------------------------------- -------- ------<BR>52 5 0 0 DB S GRANT<BR>52 1 1115151018 0 TAB IS GRANT<BR>52 5 2089058478 0 TAB X GRANT<BR><BR>t.y. lygiai tas pats kaip su transaction isolation level nustatyta i read uncommitted ir panaudojant HOLDLOCK hinta.</FONT></DIV> <DIV><FONT size=2 face=Courier>Jei visa procedura pabandyti su dviem transakcijom is skirtingu sesiju.</FONT></DIV> <DIV><FONT size=2 face=Courier></FONT> </DIV> <DIV><FONT size=2 face=Courier>T1</FONT></DIV> <DIV><FONT size=2 face=Courier></FONT> </DIV> <DIV><FONT size=2 face=Courier>begin tran<BR>set transaction isolation level read uncommitted<BR>update my_table set user_id = 'aaa'<BR>where id = (select min(id) from my_table where user_id is null)<BR>exec sp_lock<BR>waitfor delay '00:00:10'<BR>commit tran</FONT></DIV> <DIV><FONT size=2 face=Courier></FONT> </DIV> <DIV><FONT size=2 face=Courier>T2 (idetas papildomas sp_lock pries update ir panaudotas kitas user_id)</FONT></DIV> <DIV><FONT size=2 face=Courier></FONT> </DIV> <DIV><FONT size=2 face=Courier>begin tran<BR>set transaction isolation level read uncommitted<BR>exec sp_lock<BR>update my_table set user_id = 'bbb'<BR>where id = (select min(id) from my_table where user_id is null)<BR>exec sp_lock<BR>commit tran</FONT></DIV> <DIV><FONT size=2 face=Courier></FONT> </DIV> <DIV><FONT size=2 face=Courier>paleidus viena po kitos is karto matosi, kad T2 laukia kol pasibaigs T1 (kol vyksta waitfor delay)</FONT></DIV> <DIV><FONT size=2 face=Courier></FONT> </DIV> <DIV><FONT size=2 face=Courier>T1 rezultatas</FONT></DIV> <DIV><FONT size=2 face=Courier></FONT> </DIV> <DIV><FONT size=2 face=Courier>(1 row(s) affected)<BR>spid dbid ObjId IndId Type Resource Mode Status<BR>------ ------ ----------- ------ ---- -------------------------------- -------- ------<BR>52 5 0 0 DB S GRANT<BR>52 5 2089058478 0 PAG 1:114 IX GRANT<BR>52 5 2089058478 0 RID 1:114:0 X GRANT<BR>52 1 1115151018 0 TAB IS GRANT<BR>52 5 2089058478 0 TAB IX GRANT<BR>54 5 0 0 DB S GRANT</FONT></DIV> <DIV><FONT size=2 face=Courier></FONT> </DIV> <DIV><FONT size=2 face=Courier>matosi, kad irasui RID 1:114:0 yra uzdetas X lockas</FONT></DIV> <DIV><FONT size=2 face=Courier></FONT> </DIV> <DIV><FONT size=2 face=Courier>T2 rezultatas</FONT></DIV> <DIV><FONT size=2 face=Courier></FONT> </DIV> <DIV><FONT size=2 face=Courier>spid dbid ObjId IndId Type Resource Mode Status<BR>------ ------ ----------- ------ ---- -------------------------------- -------- ------<BR>52 5 0 0 DB S GRANT<BR>52 5 2089058478 0 PAG 1:114 IX GRANT<BR>52 5 2089058478 0 RID 1:114:0 X GRANT<BR>52 5 2089058478 0 TAB IX GRANT<BR>54 5 0 0 DB S GRANT<BR>54 1 1115151018 0 TAB IS GRANT</FONT></DIV> <DIV> </DIV> <DIV><FONT size=2 face=Courier><BR>(1 row(s) affected)<BR>spid dbid ObjId IndId Type Resource Mode Status<BR>------ ------ ----------- ------ ---- -------------------------------- -------- ------<BR>52 5 0 0 DB S GRANT<BR>54 5 2089058478 0 PAG 1:114 IX GRANT<BR>54 1 1115151018 0 TAB IS GRANT<BR>54 5 2089058478 0 RID 1:114:1 X GRANT<BR>54 5 2089058478 0 TAB IX GRANT<BR>54 5 0 0 DB S GRANT</FONT></DIV><FONT size=2 face=Courier></FONT><FONT size=2 face=Courier></FONT> <DIV><BR><FONT size=2 face=Courier>matosi, kad pirmasis sp_lock grazina, kad irasas RID 1:114:0 turi X locka, kuris uzdetas T1 metu. Pasibaigus T1, T2 prasuka savo update ir antrasis sp_lock iskvietimas rodo, kad X locka turi jau kitas irasas RID 1:114:1</FONT></DIV> <DIV><FONT size=2 face=Courier></FONT> </DIV> <DIV><FONT size=2 face=Courier>Tuo tarpu rezultatas lenteleje toks</FONT></DIV> <DIV><FONT size=2 face=Courier></FONT> </DIV> <DIV><FONT size=2 face=Courier>id user_id<BR>----------- ----------<BR>1 aaa<BR>2 bbb<BR>3 NULL<BR>4 NULL<BR>5 NULL</FONT></DIV> <DIV><FONT size=2 face=Courier></FONT> </DIV> <DIV><FONT size=2 face=Courier>Kaip galima matyti, T1 pakoregavo id=1 irasa, T2 pakoregavo id=2 irasa. Jokiu to paties iraso redagavimu neivyko. Butu is tiesu keista, jei ivyktu...</FONT></DIV> <DIV><FONT size=2 face=Courier></FONT> </DIV> <DIV><FONT size=2 face=Courier>Beje, as taip pat buvau neteisus del dirty read'u. Cia specialiai naudojau read uncommited transakciju isolation level, kad pademonstruoti, kad jokio "isparalelinimo" cia nera ir negali buti, nes T2 taip pat reikalingas "konkuruojantis" X lockas toj pacioj lentelej. Del to T2 gali prasideti tik po to, kai baigiasi T1.</FONT></DIV> <DIV><FONT size=2 face=Courier></FONT><FONT size=2 face=Courier></FONT><FONT size=2 face=Courier></FONT><FONT size=2 face=Courier></FONT><FONT size=2 face=Courier></FONT><FONT size=2 face=Courier></FONT><FONT size=2 face=Courier></FONT><FONT size=2 face=Courier></FONT><BR><BR><FONT size=2 face=Courier>"rl" <ask@me.for> wrote in message news:htoc2o$mba$1@trimpas.omnitel.net...<BR>> Nu nezinau, po MSSQL labai nesunkiai su table hintais galima statement <BR>> lock'us daryti.<BR>> <BR>> Rowlock'as paleidziamas is karto ivykdzius statement'a.<BR>> UPDATE Table1 WITH (ROWLOCK)<BR>> SET Field1 = 100<BR>> WHERE PKField = 1<BR>> <BR>> Rowlock'as paleidziamas tik uzbaigus tranzakcija.<BR>> UPDATE Table1 WITH (ROWLOCK, HOLDLOCK)<BR>> SET Field1 = 100<BR>> WHERE PKField = 1<BR>> </FONT></DIV></BODY></HTML>