| Author |
Topic |
|
mary_itohan
Posting Yak Master
191 Posts |
Posted - 2008-09-12 : 10:07:48
|
Hello,I have been reading up on transactions and trying to see how they work.PROBLEMwe have a table that does billing for clients. Which basically works as thus:1. check user credits and assign to a variable2. Check users total bill3. Update credits tableHowever, between 1 ( read column) and 3 (update column)...I noticed that if another sql statement hits that column before. It changes the value.How can we make sure that once a user starts to be billed another transaction cant update it until its finished ?thanks1st QUERY: BILLING TRANSACTIONDECLARE @TranName VARCHAR(20)SELECT @TranName = 'MyTransaction'BEGIN TRANSACTION @TranNameselect * from moneytable where username = 'sally'WAITFOR DELAY '00:00:10';-- Create an artificial delay while query 2 runsupdate moneytable set credits = 10 where username = 'sally'commit transaction MyTransaction2nd QUERYupdate moneytable set credits = '0' where username = 'sally' _____________________Yes O ! |
|
|
bjoerns
Posting Yak Master
154 Posts |
Posted - 2008-09-12 : 10:25:29
|
| Does it update within the 10 seconds or afterwards?If within, how did you find out? |
 |
|
|
TG
Master Smack Fu Yak Hacker
6065 Posts |
Posted - 2008-09-12 : 10:31:43
|
| Transaction Isolation Level is what you need to SET to change the affects concurrency. My guess is you will want to set it to REPEATABLE READ. But you should read about it on Books Online.Be One with the OptimizerTG |
 |
|
|
mary_itohan
Posting Yak Master
191 Posts |
Posted - 2008-09-12 : 10:49:59
|
quote: Originally posted by bjoerns Does it update within the 10 seconds or afterwards?If within, how did you find out?
2 Ways to find out1. I opened the table in Management studio and while the delay time of 2mins (in the transaction) is pending, I run query 22. the end value is the value of query 2 which is different from query 1 ( which is the transaction )_____________________Yes O ! |
 |
|
|
mary_itohan
Posting Yak Master
191 Posts |
Posted - 2008-09-12 : 10:52:27
|
quote: Originally posted by TG Transaction Isolation Level is what you need to SET to change the affects concurrency. My guess is you will want to set it to REPEATABLE READ. But you should read about it on Books Online.Be One with the OptimizerTG
I posted a thread here about locks and isolation level. But was adviced not to use them as SQL server automatically sets themSeehttp://www.sqlteam.com/forums/topic.asp?TOPIC_ID=110308quote: Originally posted by Bustaz Kool The SQL engine will assign the lock that it thinks is the most appropriate based on efficiency and the current activity. You don't assign a lock and, by and large, you don't need to worry about it. You can influence the SQL engine by using a lock hint (e.g., ROWLOCK) but this does not force the lock.If you are doing a single UPDATE statement, you don't need to worry about locks at all. The SQL engine treats that as an atomic event and so won't let anyone else change a value in the row while you are performing your update.Does that answer your question?=======================================It is impossible to imagine Goethe or Beethoven being good at billiards or golf. -H.L. Mencken, writer, editor, and critic (1880-1956)
quote: Originally posted by TG Already wrote this when I saw Bustaz Kool's post - but I'll post anyway :)The default transaction isolation level "read committed" is usually sufficient without using any explicit locking hints. Especially if you are using stored procedures where the update is virtually instantaneous (as opposed to holding the row locked from an application during user interaction). Are you experiencing any blocking problems?Be One with the OptimizerTG
_____________________Yes O ! |
 |
|
|
TG
Master Smack Fu Yak Hacker
6065 Posts |
Posted - 2008-09-12 : 11:20:17
|
| Your original question in that other thread did not lay out this scenario. Actually, your scenario was described ust as "--MY CODES GO HERE". Once you elaborated (slightly) I said that we didn't have enough info to answer your question. You never responded with the info I asked for. Now this thread is asking a different question than your elaboration from the other thread. Given your example (above) I say you DO need to change the isolation level from the default behavior. If you're interested I can post an example test for the scenario above illustrating how isolation level can change the concurrency behavior (for that specific scenario).Be One with the OptimizerTG |
 |
|
|
mary_itohan
Posting Yak Master
191 Posts |
Posted - 2008-09-12 : 11:26:11
|
quote: Originally posted by TG If you're interested I can post an example test for the scenario above illustrating how isolation level can change the concurrency behavior (for that specific scenario).Be One with the OptimizerTG
Oh, am sorry about that. Yes pls post an example, i would appreciate that.Thanks_____________________Yes O ! |
 |
|
|
bjoerns
Posting Yak Master
154 Posts |
Posted - 2008-09-12 : 12:00:34
|
| Well of course the end value is value of query 2. The update waits nicely for the select to return, then does its job?! |
 |
|
|
mary_itohan
Posting Yak Master
191 Posts |
Posted - 2008-09-12 : 12:08:16
|
| Yes, but I need help on how to get this transaction working.So that the user is billed appropriately_____________________Yes O ! |
 |
|
|
bjoerns
Posting Yak Master
154 Posts |
Posted - 2008-09-12 : 12:13:40
|
quote: 1. check user credits and assign to a variable2. Check users total bill3. Update credits tableHowever, between 1 ( read column) and 3 (update column)...I noticed that if another sql statement hits that column before. It changes the value.
If steps 1 - 3 are enclosed in a transaction, it changes the value afterwards. Isn't that the expected behaviour? |
 |
|
|
TG
Master Smack Fu Yak Hacker
6065 Posts |
Posted - 2008-09-12 : 12:18:36
|
With no locking hints or changes to trans isol level the other session is not blocked from updating the value. Here is an example:Run this 4 times:1. as is (while waitfor is waiting run the 2nd query in another window)2. leave default isol lev but UNCOMMENT locking hint on assignment of @credits "--with (updlock)"3. re-comment the locking hint. use SERIALIZABLE TransIsolLev4. use Repeatable Read TransIsolLevset nocount onuse tempdbcreate table moneytable (username varchar(10), credits int)insert moneytable values ('sally', 1)set transaction isolation level read committed --DEFAULT SETTING--set transaction isolation level serializable--set transaction isolation level repeatable readdeclare @credits int ,@msg varchar(50)print 'begin transaction'BEGIN TRANSACTION select @credits = credits from moneytable --with (updlock)where username = 'sally'print 'before waitfor (in transacation)'select @credits [@credits]WAITFOR DELAY '00:00:05'update moneytable set credits = 3 where username = 'sally'commit transaction print 'after transaction'select * from moneytable/*--2nd QUERY RUN THIS in another window while WAITFOR is runningupdate moneytable set credits = '0' where username = 'sally'*/godrop table moneytable/*---------------------------------------------------------------CASE 1:transaction isolation level read committed --defaultno locking hintResult:no blockingno deadlock2nd query ran between 2 statements in the transaction.Final Credits value: 3---------------------------------------------------------------CASE 2:transaction isolation level read committed --defaultVariable Read with UPDLOCK locking hintResult:blockingno deadlock2nd query ran AFTER 2 statements in the transaction Final Credits value: 0 (from 2nd window)---------------------------------------------------------------CASE 3:transaction isolation level Serializableno locking hintResult:blockingno deadlock2nd query ran AFTER 2 statements in the transactionFinal Credits value: 0 (from 2nd window)---------------------------------------------------------------CASE 4:transaction isolation level Repeatable Readno locking hintResult:blockingDEADLOCK - 2nd query Deadlocked and terminated as deadlock victimFinal Credits value: 3---------------------------------------------------------------*/EDIT:added redBe One with the OptimizerTG |
 |
|
|
mary_itohan
Posting Yak Master
191 Posts |
Posted - 2008-09-12 : 13:06:05
|
| Ok thank you. will try it out.brb_____________________Yes O ! |
 |
|
|
mary_itohan
Posting Yak Master
191 Posts |
Posted - 2008-09-12 : 13:14:36
|
| Sorry TG, but it doesnt work.when i run two open windows, the first window has your query and the second window has thisuse [delete]update moneytable set credits = -100 where username = 'sally'select * from moneytableI changed the delay time to WAITFOR DELAY '00:00:20'When i run your query, and then while the delay waits. I run the 2nd, and the results i get is username creditssally -97_____________________Yes O ! |
 |
|
|
TG
Master Smack Fu Yak Hacker
6065 Posts |
Posted - 2008-09-12 : 13:23:41
|
| Well, you've got different code than I did since you ended up with -97 ???what do you mean "it doesn't work"? The whole purpose was to compare the 4 different scenarios:1. read committed3. serializable4. repeatable read2. read committed and "with (updlock)" on the first readDid all four return the same results?Be One with the OptimizerTG |
 |
|
|
mary_itohan
Posting Yak Master
191 Posts |
Posted - 2008-09-12 : 13:26:58
|
| One min pls_____________________Yes O ! |
 |
|
|
mary_itohan
Posting Yak Master
191 Posts |
Posted - 2008-09-12 : 13:31:30
|
| Ok the set transaction isolation level serializable Does it for me. But one question about the isolation levels.From the last thread. I understand that the isolation level is already set. Does this instruction "RESET" the isolation level,and after the query has finished what will the isolation level be ? 2. does it affect the database when i set an isolation level ?thanks_____________________Yes O ! |
 |
|
|
TG
Master Smack Fu Yak Hacker
6065 Posts |
Posted - 2008-09-12 : 13:45:10
|
| The SET command affects the current session including any/all statements after the SET command. For as long as that session is active the isolation level will be the last value it was SET to. (if it was never set than the default level is read committed)>>does it affect the database when i set an isolation level ?Of course, but just for the session that set it. It is not a "global" setting that affects other processes unless they are attempting to concurrently access the same resources affected by the session that SET it.I believe 2 options satisfied your objective:2. read committed and "with (updlock)" on the first read3. serializableThough the affect for this test is identical between these 2 options, I think the (updlock) locking hint may be a less "aggressive" solution.Be One with the OptimizerTG |
 |
|
|
mary_itohan
Posting Yak Master
191 Posts |
Posted - 2008-09-12 : 15:18:22
|
Quite educative. Thanks a lot. One last question, How do i check the default isolation ? and after running my query, i can use the same command to set it back to the default ???_____________________Yes O ! |
 |
|
|
TG
Master Smack Fu Yak Hacker
6065 Posts |
Posted - 2008-09-12 : 15:31:58
|
| You can't set it to "default" but you can set it back to what you know the default is "read committed" by using the same SET command.You can View the current isolation level by using:dbcc useroptionsHowever, unless you explicitly set the value to something other than default, "isolation level" won't appear in the results.Be One with the OptimizerTG |
 |
|
|
afrika
Master Smack Fu Yak Hacker
2706 Posts |
Posted - 2008-09-12 : 15:37:52
|
| Are there any side effects to isolation locks, as they "MUST" use a lot of memory ? and have downsides |
 |
|
|
mary_itohan
Posting Yak Master
191 Posts |
Posted - 2008-09-12 : 15:39:37
|
quote: Originally posted by TG You can't set it to "default" but you can set it back to what you know the default is "read committed" by using the same SET command.You can View the current isolation level by using:dbcc useroptionsHowever, unless you explicitly set the value to something other than default, "isolation level" won't appear in the results.Be One with the OptimizerTG
Thanks TG_____________________Yes O ! |
 |
|
|
Next Page
|