Showing posts with label updates. Show all posts
Showing posts with label updates. Show all posts

Thursday, March 22, 2012

Deadlock Question

Hi All,

Can multiple updates on one table using single
query generate deadlock ?
For example, at the same time, there are 2 users
run 2 queries as follows :

User1 runs :
update tab1 set tab1.v = tab1.v + 1
from tab1 inner join tab2 on tab1.no = tab2.no

User2 runs :
update tab1 set tab1.v = tab1.v + 1
from tab1 inner join tab3 on tab1.no = tab3.no

Note :
The content of the column "no" on table tab2 :
('A','B','C',...,'X','Y','Z')
The content of the column "no" on table tab3
is like in table tab2, but in different order :
('Z','Y','X',....,'C','B','A')

Thanks in advance

Anita Hery

*** Sent via Developersdex http://www.developersdex.com ***
Don't just participate in USENET...get rewarded for it!Anita (anonymous@.devdex.com) writes:
> Can multiple updates on one table using single
> query generate deadlock ?
> For example, at the same time, there are 2 users
> run 2 queries as follows :
> User1 runs :
> update tab1 set tab1.v = tab1.v + 1
> from tab1 inner join tab2 on tab1.no = tab2.no
> User2 runs :
> update tab1 set tab1.v = tab1.v + 1
> from tab1 inner join tab3 on tab1.no = tab3.no
> Note :
> The content of the column "no" on table tab2 :
> ('A','B','C',...,'X','Y','Z')
> The content of the column "no" on table tab3
> is like in table tab2, but in different order :
> ('Z','Y','X',....,'C','B','A')

Tables in a relational database are sets, and data has no order.

But, of course, for the evaluation of a query the physical order may
affect such things as deadlock.

Anyway, I am not going to answer the question directly, because there
is a lot of unknown elements. Is tbl.v a primary key or at least
indexed? What about tbl2.no and tbl3.no? And what exactly is
different order?

CREATE TABLE statements for the tables and INSERT statemetns for the
data may help.

--
Erland Sommarskog, SQL Server MVP, sommar@.algonet.se

Books Online for SQL Server SP3 at
http://www.microsoft.com/sql/techin.../2000/books.asp|||Erland Sommarskog,

Thanks for your reply.

Deadlock can be found easily in several command steps.
But, how can I find it in multiple updates using
only one step of command ?

This question is posted because I do not know
exactly how SQL Server handles my sample query.
And I become worry after reading many deadlock
articles here. Especially deadlock that is caused
by table index.

Below is the description of the tables :

Table tb1 :
- no CHAR(10); no2 CHAR(10); v INT
- Index possibility : only one index, on no or on no2
- no is unique, no2 is unique
- v is not a key.

Table tb2 :
- x CHAR(10); no CHAR(10)
- Index : on x
- x is not unique, no is unique

Table tb3 :
- x CHAR(10); no CHAR(10)
- Index : on x
- x is not unique, no is unique

Regards,

Anita Hery

*** Sent via Developersdex http://www.developersdex.com ***
Don't just participate in USENET...get rewarded for it!|||Anita (anonymous@.devdex.com) writes:
> Deadlock can be found easily in several command steps.
> But, how can I find it in multiple updates using
> only one step of command ?

Testing deadlocks that may occur from single statements are indeed not
trivial to construct at will.

One possibility is to write a small app - could even be a stored procedure
- that runs the supicious SQL statement all over again in an infinite
loop. If you get a deadlock, you now know that it can happen. If you
don't get a deadlock - well you still don't know, because may the test
was not good enough.

Another approach is to introduce a waitstate somewhere, so that you get
a chance to start a second query window with the competing query. This
is not trivial either. For a simple case, I used this function some
time ago:

create function nisse () returns int as
begin
exec master..xp_cmdshell 'osql -E -n -Q "WAITFOR DELAY ''00:00:20''"'
return 1
end

In your case, at least one your updates should read:

UPDATE tbl
SET col = dbo.nisse() -- Or some expression including dbo.nisse().
...

But of course, this constructs a situation which is not really the same
as the real-world scenario, and the observations may not be transferrable.
(But it seems to me that in this case, they could.)

Since you did not provide CREATE TABLE statements and INSERT statements
with sample data, I was too lazy to actually try this technique with
your example. :-)

--
Erland Sommarskog, SQL Server MVP, sommar@.algonet.se

Books Online for SQL Server SP3 at
http://www.microsoft.com/sql/techin.../2000/books.asp|||When SQL Server receive query :
update tab1 set tab1.v = tab1.v + 1
from tab1 inner join tab2 on tab1.no = tab2.no
I expect it follows the procedure like this :
a. Find the rows that will be updated.
b. If they are not found then exit.
c. Try locking the rows found.
d. If locking is successfull then update the
rows and exit.
e. Wait for miliseconds.
f. If query timeout expires then exit.
g. goto c.

Since I do not have information about how SQL Server
handles the query, I usually insert tablock hint in the query :
update tab1 with (tablock) set tab1.v = tab1.v + 1
from tab1 inner join tab2 on tab1.no = tab2.no

Though by using tablock hint it will lock all rows
in the table (prevent other rows from being updated
by other users) but, I think I should take this way.
It is free from deadlock.

Anita Hery

*** Sent via Developersdex http://www.developersdex.com ***
Don't just participate in USENET...get rewarded for it!|||Anita (anonymous@.devdex.com) writes:
> When SQL Server receive query :
> update tab1 set tab1.v = tab1.v + 1
> from tab1 inner join tab2 on tab1.no = tab2.no
> I expect it follows the procedure like this :
> a. Find the rows that will be updated.
> b. If they are not found then exit.
> c. Try locking the rows found.
> d. If locking is successfull then update the
> rows and exit.
> e. Wait for miliseconds.
> f. If query timeout expires then exit.
> g. goto c.

I have to admit that I don't fully master the internal procedure, but
I would expect it to be somewhat different. I would expect that already
when SQL Server finds the matching rows that it applies at least
shared locks, possible also intent locks. Once a row is found to
qualify, I would suppose SQL Server puts an exclusive lock on a
row.

You mention "query timeout". I suppose you mean lock timeout, which you
control with SET LOCK_TIMEOUT. Query timeout is a client (mis)feature,
and does not affect locking.

Going back to your original post, you had these two statements:

User1 runs :
update tab1 set tab1.v = tab1.v + 1
from tab1 inner join tab2 on tab1.no = tab2.no

User2 runs :
update tab1 set tab1.v = tab1.v + 1
from tab1 inner join tab3 on tab1.no = tab3.no

Working from my assumptions above - which I like to stress are nothing
but assumptions, you could get a deadlock here, if the statistics on
the table are such that the optimizer chooses different query plans.
For instance, for the first query, the optimizer decides to scan tab1
and then perform a nested join with tab2. But for the second query,
the optimizer scans tab3, and performs a nested join with index seek
on tab1. If the two queries start at the same time, they will find
matching rows in tab1 in different order, and therefor they will
deadlock.

> Since I do not have information about how SQL Server
> handles the query, I usually insert tablock hint in the query :
> update tab1 with (tablock) set tab1.v = tab1.v + 1
> from tab1 inner join tab2 on tab1.no = tab2.no
> Though by using tablock hint it will lock all rows
> in the table (prevent other rows from being updated
> by other users) but, I think I should take this way.
> It is free from deadlock.

Yes, this should be deadlock free. But there are of course other issues
with tablock. If most updates are on single rows, tablock might be too
heavy-handed and lead to concurrency issues.

--
Erland Sommarskog, SQL Server MVP, sommar@.algonet.se

Books Online for SQL Server SP3 at
http://www.microsoft.com/sql/techin.../2000/books.asp|||Erland Sommarskog,

Thanks for your reply,

Yes, your assumption is somewhat different with what I expect. I expect
: if there are 10 matching rows and SQL Server can lock only 9 rows,
then : SQL Server unlock 9 rows, wait for a moment, and try locking 10
rows again.
If my expectation is true, then the query is deadlock free and I will
avoid using tablock hint.

My last question is where I can get information that tell us your
assumption or my expectation is true ?

Regards,
Anita Hery

*** Sent via Developersdex http://www.developersdex.com ***
Don't just participate in USENET...get rewarded for it!|||Anita (anonymous@.devdex.com) writes:
> Yes, your assumption is somewhat different with what I expect. I expect
>: if there are 10 matching rows and SQL Server can lock only 9 rows,
> then : SQL Server unlock 9 rows, wait for a moment, and try locking 10
> rows again.
> If my expectation is true, then the query is deadlock free and I will
> avoid using tablock hint.
> My last question is where I can get information that tell us your
> assumption or my expectation is true ?

So much I can tell with confidence, that SQL Server never releases locks
because it cannot get all locks it needs to carry out a task. While such
a strategy could reduce deadlock, it could have other nasty effects like
lock starvation. A process that needs to access many rows in a busy system
would never get all locks.

Also, I believe that the work order is something like: lock one row,
update that row, lock next row and so on. In this case, it is of course
even less possible to release rows.

--
Erland Sommarskog, SQL Server MVP, sommar@.algonet.se

Books Online for SQL Server SP3 at
http://www.microsoft.com/sql/techin.../2000/books.asp|||Erland Sommarskog,

Thanks for all your replies.

Regards,
Anita Hery

*** Sent via Developersdex http://www.developersdex.com ***
Don't just participate in USENET...get rewarded for it!

Wednesday, March 21, 2012

Deadlock on Update Statement (NOLOCK)

I have the following updates statements in my stored procedure which caused
a deadlock. Should I take the (NOLOCK) statement out of the update
statements?
Is there some else I can to help resolve this deadlock?
Thanks,
Update SRA_FlowMaster
Set Status = 'I'
From SRA_FlowMaster New
Inner Join SRA_FlowMaster (NoLock)
On New. FlowMasterNo = SRA_FlowMaster. FlowMasterNo
And New.TypeCode = SRA_FlowMaster. TypeCode
WhereNew. FlowMasterID = @.i_FlowMasterID
And SRA_FlowMaster. FlowMasterID <> @.i_FlowMasterID
And SRA_FlowMaster. Status In ('K', 'M')
Update SRA_FlowMaster
Set Status = 'I'
From SRA_FlowMaster New
Inner Join SRA_FlowMaster (NoLock)
On New. FlowMasterNo = SRA_FlowMaster. FlowMaster
And New.TypeCode = SRA_FlowMaster. TypeCode
Where New. FlowMasterID = @.i_FlowMasterID
And SRA_FlowMaster. FlowMasterID <> @.i_FlowMasterID
And SRA_FlowMaster. Status = 'A'
And New. Status In ('A', 'D')Joe,
A deadlock involved two processes requesting a resource being locked by the
other. You have to identify the processes and the statements causing the
deadlock. The table hint you are using is not a hint to prevent deadlocks.
See "Minimizing Deadlocks" and "Troubleshooting Deadlocks" in BOL for more
information.
Tracing Deadlocks
http://www.sqlservercentral.com/col...ngdeadlocks.asp
AMB
"Joe K." wrote:

> I have the following updates statements in my stored procedure which cause
d
> a deadlock. Should I take the (NOLOCK) statement out of the update
> statements?
> Is there some else I can to help resolve this deadlock?
> Thanks,
>
> Update SRA_FlowMaster
> Set Status = 'I'
> From SRA_FlowMaster New
> Inner Join SRA_FlowMaster (NoLock)
> On New. FlowMasterNo = SRA_FlowMaster. FlowMasterNo
> And New.TypeCode = SRA_FlowMaster. TypeCode
> WhereNew. FlowMasterID = @.i_FlowMasterID
> And SRA_FlowMaster. FlowMasterID <> @.i_FlowMasterID
> And SRA_FlowMaster. Status In ('K', 'M')
> Update SRA_FlowMaster
> Set Status = 'I'
> From SRA_FlowMaster New
> Inner Join SRA_FlowMaster (NoLock)
> On New. FlowMasterNo = SRA_FlowMaster. FlowMaster
> And New.TypeCode = SRA_FlowMaster. TypeCode
> Where New. FlowMasterID = @.i_FlowMasterID
> And SRA_FlowMaster. FlowMasterID <> @.i_FlowMasterID
> And SRA_FlowMaster. Status = 'A'
> And New. Status In ('A', 'D')
>|||Hmm. Let me guess.
'Status' has only a handful of values.
You have an index on 'Status'.
Almost all of the values of 'Status' are the same.
This is a pretty common issue. Status fields are really a bad way to
represent and control status of an object, even thought they seem intuitive
at first. The key range locking required on an update makes it almost
impossible to scale to any reasonable level.
You can drop the index on Status but you will probably time out on some
other queries. (NOLOCK) hints won't change the inherent locking required to
do an update. Your problem is architectural and will require adjusting the
schema to fix. I would represent Status as a work queue using another
table. The presence of a pointer to the Primary Key indicates the status.
If there is no entries, then the status is whatever the most common status
(I.E. 'Closed', 'C', 'Paid', depending on the context) actually is.
Geoff N. Hiten
Microsoft SQL Server MVP
"Joe K." <Joe K.@.discussions.microsoft.com> wrote in message
news:BED3489D-5AC1-48A7-B785-C9EF6128573B@.microsoft.com...
> I have the following updates statements in my stored procedure which
> caused
> a deadlock. Should I take the (NOLOCK) statement out of the update
> statements?
> Is there some else I can to help resolve this deadlock?
> Thanks,
>
> Update SRA_FlowMaster
> Set Status = 'I'
> From SRA_FlowMaster New
> Inner Join SRA_FlowMaster (NoLock)
> On New. FlowMasterNo = SRA_FlowMaster. FlowMasterNo
> And New.TypeCode = SRA_FlowMaster. TypeCode
> WhereNew. FlowMasterID = @.i_FlowMasterID
> And SRA_FlowMaster. FlowMasterID <> @.i_FlowMasterID
> And SRA_FlowMaster. Status In ('K', 'M')
> Update SRA_FlowMaster
> Set Status = 'I'
> From SRA_FlowMaster New
> Inner Join SRA_FlowMaster (NoLock)
> On New. FlowMasterNo = SRA_FlowMaster. FlowMaster
> And New.TypeCode = SRA_FlowMaster. TypeCode
> Where New. FlowMasterID = @.i_FlowMasterID
> And SRA_FlowMaster. FlowMasterID <> @.i_FlowMasterID
> And SRA_FlowMaster. Status = 'A'
> And New. Status In ('A', 'D')
>

Deadlock on single table

We have one user who enters a transaction and then does a single row
update (updates all columns but only one is changing - this is due to
the way our sql is generated in the application), at this point
another user enter a transaction and tries to update the same row (he
understandably has to sit and wait while he is blocked by the original
user). The original user then updates the same row again at this
point the second user is chosen as a deadlock victim and killed. If I
try and recreate this with any other tables(or pubs) I get my expected
behaviour of the original user just doing 2 successful updates and the
second user then completing his update once the original user has
either committed his changes or rolled back. The query plan indicates
that a drop and insert of the row is happening (this is not the case
with any other tables where we get our expected behaviour). This only
happens when the index is clustered - if we use a non-clustered index
it does not occur.

Is this expected behaviour? it seems dangerous to me as the first
user has not commited or rolled back his updates. It was only
highlighted by a fault in our application that caused the second
update to be executed.

I have some thoughts about it being something to do with a row lock
being relased due to a delete / insest of the row in the second update
(we see this in the execution plan)....

Any help much appreciated as I am struggling to get my head round how
the second user was ever able to get hold of the resource.
CODA PBC wrote:

> We have one user who enters a transaction and then does a single row
> update (updates all columns but only one is changing - this is due to
> the way our sql is generated in the application), at this point
> another user enter a transaction and tries to update the same row (he
> understandably has to sit and wait while he is blocked by the original
> user). The original user then updates the same row again at this
> point the second user is chosen as a deadlock victim and killed. If I
> try and recreate this with any other tables(or pubs) I get my expected
> behaviour of the original user just doing 2 successful updates and the
> second user then completing his update once the original user has
> either committed his changes or rolled back. The query plan indicates
> that a drop and insert of the row is happening (this is not the case
> with any other tables where we get our expected behaviour). This only
> happens when the index is clustered - if we use a non-clustered index
> it does not occur.
> Is this expected behaviour? it seems dangerous to me as the first
> user has not commited or rolled back his updates. It was only
> highlighted by a fault in our application that caused the second
> update to be executed.
> I have some thoughts about it being something to do with a row lock
> being relased due to a delete / insest of the row in the second update
> (we see this in the execution plan)....
> Any help much appreciated as I am struggling to get my head round how
> the second user was ever able to get hold of the resource.

Hi. The trouble is that there is more than one lockable object
usually involved in an update. The datarow/page, and likely one
or more index page. It is unfortunate that with the clustered index,
your two users are obtaining those locks in different orders (a function
of the different query plans), causing a deadlock. I suppose that if both
updaters used the same plan (sending the exact same SQL), you would get
the behavior you want. It is sadly ugly that the generated code is
updating every column to change only one. Particularly if the change
includes the clustered key column(s), because it tells the DBMS that the
row has to be deleted from the clustered index (the last nodes of which
are the data pages), and re-inserted where the new key values dictate.
(It might be a fond hope that the DBMS could examine the key values
could be examined and the DBMS could interpret whether the row
actually has to move, but that is in reality not possible. The plan
needs to be made before the actual table data are accessed.).

I hope this helps,
Joe Weinstein at BEA

Deadlock on simple update related to clustered index

I am encountering a deadlock situation, with two threads
running two updates to the same table, if that table has a
clustered index on it that is NOT the primary key, and the
where clause of the UPDATE statement is on the primary
key. Very strange... Here is the test case:
create table x
(id int not null,
lastModified datetime not null,
altkey varchar(3) not null)
GO
CREATE UNIQUE CLUSTERED INDEX IAK_X ON x (altKey)
GO
alter table x add constraint pk_x primary key(id)
GO
insert into x
values (1, getdate(), 'XXX');
Then, from 2 ISQL threads, ran the following code...
begin tran
waitfor time '15:06' -- ensure they start at same time
update x
set lastModified = getdate()
where id = 1;
waitfor delay '000:00:10' -- wait to ensure lock occurs
update x
set lastModified = getdate()
where id = 1;
commit tran;
When I monitor the locks, the following happens:
Thread A successfully performs Update 1
Thread B is blocked as A has Exclusive lock on the row.
Thread B, however, successfully gets a KEY UPDATE lock on
PK_X
Thread A, when it tries to perform Update 2, is blocked
trying to get a KEY UPDATE lock on PK_X, causing the
deadlock.
Even if I then drop the clustered index with
DROP INDEX x.iak_x;
the problem remains.
However, if I NEVER create the clustered index. The
threads both work fine and never encounter a deadlock.
Neither transaction attempts to get a KEY UPDATE lock on
the primary key index PK_X.
We try to use clustered indexes on fields other than the
ID # (one-up number, but NOT an IDENTITY column in this
case), because we encountered deadlocks on Inserts in the
past.
Any help would be greatly appreciated.On Thu, 24 Jul 2003 14:02:58 -0700, "Corey" <chorton1@.austin.rr.com>
wrote:
>Any help would be greatly appreciated.
That's pretty humorous.
I've never gotten into the detailed guts of SQLServer like some around
here, but it sounds to me like you've hit a SQLServer bug. It looks
like SQLServer locks the data record in thread A, but allows thread B
to begin and get a lock on an index entry while waiting for the data,
and voila, deadlock. If that is the case, I'd call it a bug.
I assume it works correctly if you have the PK on id?
J.sql

Sunday, March 11, 2012

Deadlock & probably other problem

Hi,

We are having sql server 7. But recently when we executing a batch of SQL in that some updates were there & those updates causes triggers needs to be fired. But batch gets teminated in between. We checked the error logs & found that Few other processes are running continously like SPid 14 etc which are opening & closing the datafiles for pubs, & northwind database. Why? Is this a server settings problem Or Virus?

For deadlock is nested triggeres becomes problem after 3-4 level deep on multiple tables?

ThanksThere are a number of things which can make deadlocks more frequent.
One is long running transactions. Triggers cause the transaction to extend for the length of the trigger and also make the actual update less likely to be efficient so can cause the problem - nested triggers even more so.

>> opening & closing the datafiles
Which version do you have? It sounds like these databases are set to autoclose which is a bit odd - I would have said maybe it's a checkpoint but spid 14 doesn't sound like a system spid. Do you have anything monitoring databases or maybe backup software.

Try running this sp
http://www.nigelrivett.net/sp_nrSpidByStatus.html
it will tell you what the last statement executed by a spid is.
You could also use the profiler to see what is happenning but that will also slow down the system.|||Hi
Thanks For Reply.
For Triggers i reduced the transactions time & batch size.

For opening closing datafile the content in log files were like this

2003-07-08 08:39:08.00 spid33 Starting up database 'Northwind'.
2003-07-08 08:39:08.00 spid33 Opening file d:\SQLData\DATA\northwnd.mdf.
2003-07-08 08:39:08.12 spid33 Opening file d:\SQLData\DATA\northwnd.ldf.
2003-07-08 08:39:08.39 spid33 Closing file d:\SQLData\DATA\northwnd.mdf.
2003-07-08 08:39:08.43 spid33 Closing file d:\SQLData\DATA\northwnd.ldf.
2003-07-08 08:39:08.45 spid33 Starting up database 'pubs'.
2003-07-08 08:39:08.45 spid33 Opening file d:\SQLData\DATA\pubs.mdf.
2003-07-08 08:39:08.46 spid33 Opening file d:\SQLData\DATA\pubs_log.ldf.
2003-07-08 08:39:08.62 spid33 Closing file d:\SQLData\DATA\pubs.mdf.
2003-07-08 08:39:08.65 spid33 Closing file d:\SQLData\DATA\pubs_log.ldf.

This happening continously. In this case the SPID is 33.

Thanks|||If you run the following command in Query Analyzer:

sp_dboption pubs

Does the output include AutoClose?|||Just set the databases to not autoclose and it should get rid of that.

Use profiler to log any accesses to those databases and you will see why it's happenning.

Sounds like there is some monitoring going on somewhere - maybe someone keeps clicking on things in enterprise manager or has a gui which tries to get info from the databases.

Thursday, March 8, 2012

Dead Lock

Hello !!!

I have 2 transactions, the first one has MANY updates to the table A and it finishes with a commit or rollback (ONLY AT THE END), the second one has only one insert into the table A that finishes with a commit or rollback, the problem is that the update process takes a long time to finish, and the insert process could be thrown during the first process, there's where I get everything locked cause the table A is locked and my java aplication gets stuck.

Note: When I execute each transaction independient I have no problems.

Is there any possibility to lock table A completly for the first transaction and release It for second one ??

Could you give me any suggestion of what to do step by step ?

Thanks !!!Are you running these processes by submitting SQL commands from your Java App, or are you just executing existing Stored Procedures?|||begin tran
select 1 from tableA (tablock) where 1=2
update...
if @.@.error != 0 begin
...
rollback tran
return (1)
end
...
commit tran