Showing posts with label procedures. Show all posts
Showing posts with label procedures. Show all posts

Tuesday, March 27, 2012

Deadlocks

Our system is reasonably complex with a lot of non-trivial stored procedures. As the load on our DB increased we're now getting more and more deadlocks (10 per day or so from about a million stored proc executions).

We try to avoid transactions where we can, and we do attempt to optimse stored procs to steer clear of deadlock conditions, but with the sheer number of stored procedures we can't possibly avoid all deadlock conditions.

One solution I'm considering is to re-run stored procs that failed because of a deadlock. In the .net code we'll run the stored proc, check for a deadlock error and if one happened, wait 100ms and try again.

What do you guys think?SQL-Server-Performance.com is a site that I use often to help me with situations such as this.

They have an article calledTips for Reducing SQL Server Deadlocks which I highly recommend. Part of that article states "Most well-designed applications, after receiving a deadlock message, will resubmit the aborted transaction, which most likely can now run successfully.", which is exactly what you are proposing to do so it is sounding like a good idea.

These 3 suggestions have all but eliminated deadlocking for me:
-- Keep transactions as short as possible
-- Reduce lock time
-- Consider using the NOLOCK hint

Terri|||Thanks, that's what I wanted to see.

Our solution then:

- All stored procedures with no updates / deletes will use SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

- I'll overload the SqlCommand.ExecuteNonQuery() method to re-run deadlocked transactions

- In transactions doing updates / deletes we'll use the NOLOCK hint where serializability is not required

in addition to our current practices:

- Only use transactions where serializability is required

- Keep the transaction as short as possible

- Optimise select statements in transactions with indexes on non-trivial tables

Cheers for that link Terri|||I would definitely use NOLOCKs on any queries that "dirty reads" are ok. Also, you can use WITH (ROLOCK) on update and delete statements where you are deleting one row. Such as deleting based on a Primary key.|||Do you know what type of Deadlocks you're are getting, lock promotion deadlocks or the more traditional resource contention type?|||Just regular resource contention ones.|||Pierre, Can you give an example of how you ended up re-running the transaction? I am having the same problems, I get about 5-10 per day also. Any help would be appriciated!
Thanks,
Jason|||

Try the code below it is what is recommended by my book SQL Server 2000 A beginner's guide by Dusan Petkovic. But this code is for SQL Server 2005 so test it. The code is from the link below. The key is to write a conditional statement that will return SQL Server @.@. ERROR 1205 which is Deadlock. Run a search for SET DEADLOCK_PRIORITY in the BOL (books online). Hope this helps.
CREATE PROCEDURE DeadLock_Test AS

SET NOCOUNT ON
SET XACT_ABORT ON
SET DEADLOCK_PRIORITY LOW

DECLARE @.Err INTEGER
DECLARE @.ErrMsg VARCHAR(200)

RETRY:
BEGIN TRY
BEGIN TRANSACTION
UPDATE tblContact SET LastName = 'SP_LastName_1' WHERE ContactID = 1
UPDATE tblContact SET LastName = 'SP_LastName_2' WHERE ContactID = 2
COMMIT TRANSACTION
END TRY
BEGIN CATCH
SET @.Err = @.@.ERROR
IF @.Err = 1205
ROLLBACK TRANSACTION
INSERT INTO ErrorLog (ErrID, ErrMsg) VALUES (@.Err, 'Deadlock recovery attempt.')
WAITFOR DELAY '00:00:10'
GOTO RETRY
IF @.Err = 2627
SET @.ErrMsg = 'PK Violation.'
IF @.ErrMsg IS NULL
SET @.ErrMsg = 'Other Error.'
INSERT INTO ErrorLog (ErrID, ErrMsg) VALUES (@.Err, @.ErrMsg)
END CATCH
http://www.campbellassociates.ca/blog/CategoryView.aspx?category=SQL%20Server

|||

Pierre,

I finally found my error now after a year, when they say use Query Analyizer They mean it. I had a stupid trigger that I had written way before I knew what I was doing (I still don't) but anyway the trigger was poorly written and actuall not needed. No More Deadlocks!!! Weheww!!! So I think the moral to the story is don't use Triggers Unless you absolutely have to.

sql

deadlocks

It would appear that I am having a strange deadlock error. I have two
different stored procedures that are both inserting into the same table.
Other than that they have nothing in common. One of the procs has a locking
hint of (TABLOCK, HOLDLOCK) on the insert so that the table isn't modified
until after the tranaction is completed. I thought that deadlocking was the
locking of two tables by two processes that that the other wanted? I didn't
think that dead locks could happen with two processes and one table.Hi Wilbur
There are two major / common deadlock
scenarios. "Cyclical" deadlocking is where two connections
acquire locks on objects in reverse order, deadlocking
each other. "Conversion" deadlocking occurs when two
connections acquire shared locks on the same resource (eg
table) but then both want to convert the shared lock to
exclusive. Because they both already hold a shared lock on
that resource, who's to say either should let go first -
therefore they deadlock.
Your scenario sounds to me like a conversion deadlock
scenario. Your use of HOLDLOCK indicates you're acquiring
a shared lock (eg select). If you insert into that same
table, the connections will try to convert that shared
lock they're already holding to exclusive & deadlock each
other.
In short, what you might really want is UPDLOCK, which
acquires a lock that always be converted to exclusive
(almost like acquiring an exclusive in the first place) &
therefore avoids the conversion deadlock scenario.
HTH
Regards,
Greg Linwood
SQL Server MVP
>--Original Message--
>It would appear that I am having a strange deadlock
error. I have two
>different stored procedures that are both inserting into
the same table.
>Other than that they have nothing in common. One of the
procs has a locking
>hint of (TABLOCK, HOLDLOCK) on the insert so that the
table isn't modified
>until after the tranaction is completed. I thought that
deadlocking was the
>locking of two tables by two processes that that the
other wanted? I didn't
>think that dead locks could happen with two processes and
one table.
>
>.
>

Thursday, March 22, 2012

deadlock problem

I have an application that calls many stored procedures. They are
occassionally getting into a deadlock situation.
I have used DBCC TraceOn (-1,1204) to trace the problem and have had
moderate success. However, I have hit a particular deadlock that I just
don't understand and was hoping someone here may be able to help.
The two sps in question are Item_I and Item_DNPK.
The output from DBCC Trace (see below) tells me that SPID 60 (see red text)
has an exclusive (X) lock on the Item table index (KEY: 10:613577224:1 is a
clustered index XPKItem). SPID 60 is currently deadlocked at line 29 of
Item_I. Line 29 is the very first transaction in this sp.
The other client, SPID 56 (see green text) has a Range-Shared-Update lock on
the same resource as SPID 60 and is currently deadlocked at line 60 of
Item_DNPK. Line 60 is the very first meaningful transaction in this sp (not
counting declares and create operations on #temp tables).
The deadlock is, I think, occurring because SPID 60, which has an X lock on
the resource, is waiting for a Range-Insert-Null lock (see maroon text),
while SPID 56 is waiting for a Range-S-U lock on the same resource.
What I don't understand is why there is a deadlock in this case; with one
resource? Also, how can I prevent it, given that the lines in question are
right at the beginning of the transactions in the respective sps?
Any help would be very much appreciated
Adrian
Output of DBCC TraceOn (1204) for the deadlock described above::
2006-02-21 14:25:06.21 spid4
2006-02-21 14:25:06.21 spid4 Node:1
2006-02-21 14:25:06.21 spid4 KEY: 10:613577224:1 (100095e758e0)
CleanCnt:1 Mode: X Flags: 0x0
2006-02-21 14:25:06.21 spid4 Grant List 0::
2006-02-21 14:25:06.21 spid4 Owner:0x42be3fe0 Mode: X Flg:0x0
Ref:0 Life:02000000 SPID:60 ECID:0
2006-02-21 14:25:06.21 spid4 SPID: 60 ECID: 0 Statement Type: INSERT
Line #: 29
2006-02-21 14:25:06.21 spid4 Input Buf: RPC Event: dbo.Item_I;1
2006-02-21 14:25:06.21 spid4 Requested By:
2006-02-21 14:25:06.21 spid4 ResType:LockOwner Stype:'OR' Mode:
Range-S-U SPID:56 ECID:0 Ec:(0x44111368) Value:0x42bd7920 Cost:(0/0)
2006-02-21 14:25:06.21 spid4
2006-02-21 14:25:06.21 spid4 Node:2
2006-02-21 14:25:06.21 spid4 KEY: 10:613577224:1 (ffffffffffff)
CleanCnt:1 Mode: Range-S-U Flags: 0x0
2006-02-21 14:25:06.21 spid4 Grant List 0::
2006-02-21 14:25:06.21 spid4 Owner:0x42bd85a0 Mode: Range-S-U Flg:0x0
Ref:0 Life:02000000 SPID:56 ECID:0
2006-02-21 14:25:06.21 spid4 SPID: 56 ECID: 0 Statement Type: INSERT
Line #: 60
2006-02-21 14:25:06.21 spid4 Input Buf: RPC Event: dbo.Item_DNPK;1
2006-02-21 14:25:06.21 spid4 Requested By:
2006-02-21 14:25:06.21 spid4 ResType:LockOwner Stype:'OR' Mode:
Range-Insert-Null SPID:60 ECID:0 Ec:(0x4428D368) Value:0x42bd29e0
Cost:(0/214)
2006-02-21 14:25:06.21 spid4 Victim Resource Owner:
2006-02-21 14:25:06.21 spid4 ResType:LockOwner Stype:'OR' Mode:
Range-S-U SPID:56 ECID:0 Ec:(0x44111368)See if this helps
http://sql-server-performance.com/deadlocks.asp
Madhivanan|||Please post the queries.
ML
http://milambda.blogspot.com/|||Here are the two queries involved in the deadlck I am referring to:
Query 1 - sp Item_DNPK (I have left some of this stored proc out just
because it is very long. My deadlocking is happening on the Insert so I
don't think the rest of the sp (after this Insert) is relevant. If you think
it will help, I can post it as well):
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ --SERIALIZABLE--
BEGIN TRAN
CREATE TABLE #Temp (MimeElementKey int)
-- primary key has to exist in order to prevent the subsequent deletes
from hanging
CREATE TABLE #Temp2 (ItemKey int not null , ParentKey int,
RecursionDepth int not null,
PRIMARY KEY CLUSTERED
(
[ItemKey],
[RecursionDepth]
))
-- get the dependent items of the initial item being deleted
INSERT INTO #Temp2
SELECT ItemKey, ParentKey, @.RecursionDepth
FROM [dbo].[Item] WITH (UPDLOCK,HOLDLOCK)
WHERE ParentKey = @.aItemKey
END
Query 2: Item_I:
CREATE PROC [dbo].[Item_I]
----
--
-- Schema Version : 2.2 Build 198 Revision 0
-- Date Generated : Mon Feb 20 09:56:52 2006
-- Author : Generated from schema stored procedure template 'SP_I'
-- Description : Generic identity based insert stored procedure for
table 'Item'
-- Returns : New Identity Key if successful or negative error
number
----
--
@.aItemTypeKey int ,
@.aParentKey int ,
@.aItemPartitionKey int ,
@.aOwnerKey int ,
@.aExternalKey sql_variant ,
@.aName nvarchar(256) ,
@.aDescription nvarchar(256) ,
@.aInternal varbinary(100) ,
@.aIsLeaf bit = 0,
@.aIsDeleted bit = 0,
@.aCreatedOn datetime ,
@.aModifiedOn datetime
AS
BEGIN
DECLARE @.Result int
SET NoCount ON
INSERT INTO [dbo].[Item]
(
ItemTypeKey,
ParentKey,
ItemPartitionKey,
OwnerKey,
ExternalKey,
Name,
Description,
Internal,
IsLeaf,
IsDeleted,
CreatedOn,
ModifiedOn
)
VALUES
(
@.aItemTypeKey,
@.aParentKey,
@.aItemPartitionKey,
@.aOwnerKey,
@.aExternalKey,
@.aName,
@.aDescription,
@.aInternal,
@.aIsLeaf,
@.aIsDeleted,
@.aCreatedOn,
@.aModifiedOn
)
IF (@.@.Error = 0)
BEGIN
SELECT @.Result = @.@.Identity
END
ELSE
BEGIN
SELECT @.Result = -@.@.Error
END
RETURN @.Result
END
"ML" <ML@.discussions.microsoft.com> wrote in message
news:D0BAC95E-35B8-47A2-9F51-2BF174E5EF0F@.microsoft.com...
> Please post the queries.
>
> ML
> --
> http://milambda.blogspot.com/|||Comments inline:

> SET TRANSACTION ISOLATION LEVEL REPEATABLE READ --SERIALIZABLE--
Repeatable read? Is there another reason for this isolation level? As far as
I see it you could just use defaults here (READ COMMITED).

> BEGIN TRAN
> CREATE TABLE #Temp (MimeElementKey int)
> -- primary key has to exist in order to prevent the subsequent deletes
> from hanging
> CREATE TABLE #Temp2 (ItemKey int not null , ParentKey int,
> RecursionDepth int not null,
> PRIMARY KEY CLUSTERED
> (
> [ItemKey],
> [RecursionDepth]
> ))
> -- get the dependent items of the initial item being deleted
> INSERT INTO #Temp2
> SELECT ItemKey, ParentKey, @.RecursionDepth
> FROM [dbo].[Item] WITH (UPDLOCK,HOLDLOCK)
The HOLDLOCK hint instructs the procedure not to release the lock until it
ends. As I see it you select a set of values here and store them in a local
temporary table, I guess you make a few changes, then update the values
appropriately or what? Could you do these in a single update statement? It
would really help if we could see the rest of the procedure here - especiall
y
the part where the explicit lock is acquired.
Also try adding the ROWLOCK hint.

> WHERE ParentKey = @.aItemKey
> END
The other procedure looks OK to me. It's a simple insert procedure, and has
little or no room for improvement. I, personally, prefer the INSERT...SELECT
syntax to INSERT...VALUES, but I've never heard that choosing either one
would affect locking.
ML
http://milambda.blogspot.com/|||Thanks for the reply.
I tried these two isolation levels (REPEATABLE READ and SERIALIZABLE), but
they don't seem to make a dramatic difference. I'm a little in the dark
ragarding this deadlock, so I must admit that I don't really know whether
READ REPEATABLE is better than READ COMMITTED or not.
The rest of this stored procuder involves several (7 or 8) different
delete/update queries which themselves were involved in earlier deadlocks.
It is for that reason I had started introducing these non-default isolation
levels. Again, though, I am largely driving by the seat of my pants, here;
no explicit reason for having done that.
The reason for the temp table is actually this: my schema is represented as
meta data within several tables and I need to delete a hierarchy of items
defined within this meta schema. To do this, I recurse the sp looking for
children of items at each level. I place the identifiers of all affected
items in the #temp table and then, as I come out of the recursion, I delete
and update various aspects of my schema to delete the children in a clean
and orderly fashion. The semantics of the sp may not make much sense to you
since the rest of the schema is not known to you. IF you have any questions,
though, I will be happy to try and work through them with you.
Thanks for your help in looking into this.
Here is the rest of the sp:
CREATE PROC [dbo].[Item_DNPK]
----
--
-- Schema Version : 2.2 Build 198 Revision 0
-- Date Generated : Mon Feb 20 09:56:52 2006
-- Author : APD
-- Description : Cascade primary key based delete stored procedure for
table 'Item'
-- Recursively calls into itself deleting all children of
the
-- item passed in as the parameter
-- Returns : Zero if successful or negative error number
-- Returns : and List of dependent items that were deleted during
the cascade
----
--
@.aItemKey int,
@.RecursionDepth int = 0
AS
BEGIN
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ --SERIALIZABLE--
DECLARE @.IsLocalTran bit
DECLARE @.Result int
-- This procedure is recursive; keep track of the depth of recursion
SELECT @.RecursionDepth = @.RecursionDepth + 1
IF (@.@.TranCount = 0)
BEGIN
SET @.IsLocalTran = 1
BEGIN TRAN
END
ELSE
BEGIN
SET @.IsLocalTran = 0
END
SET @.Result = IsNull(Object_Id('tempdb..#Temp'), 0)
IF ((@.Result > 0) AND (@.RecursionDepth = 1))
BEGIN
DROP TABLE #Temp
END
-- A temporary table to hold the cascaded item Ids for later deletion
SET @.Result = IsNull(Object_Id('tempdb..#Temp2'), 0)
IF ((@.Result > 0) AND (@.RecursionDepth = 1))
BEGIN
DROP TABLE #Temp2
END
-- for the first entry, create holding tables
IF (@.RecursionDepth = 1)
BEGIN
CREATE TABLE #Temp (MimeElementKey int)
-- primary key has to exist in order to prevent the subsequent deletes
from hanging
CREATE TABLE #Temp2 (ItemKey int not null , ParentKey int,
RecursionDepth int not null,
PRIMARY KEY CLUSTERED
(
[ItemKey],
[RecursionDepth]
))
-- get the dependent items of the initial item being deleted
INSERT INTO #Temp2
SELECT ItemKey, ParentKey, @.RecursionDepth
FROM [dbo].[Item] WITH (UPDLOCK,HOLDLOCK)
WHERE ParentKey = @.aItemKey
END
ELSE
BEGIN
-- get the dependent items of the items at the previous recursion level
INSERT INTO #Temp2
SELECT i.ItemKey, i.ParentKey, @.RecursionDepth
FROM [dbo].[Item] i WITH (UPDLOCK,HOLDLOCK)
JOIN #Temp2 t WITH (NOLOCK)
ON i.ParentKey = t.ItemKey
WHERE t.RecursionDepth = @.RecursionDepth-1
END
-- if the "get" of dependent children returned a non-zero number of items,
recurse to get their children
IF (SELECT @.@.ROWCOUNT) > 0
BEGIN
-- get these children to delete as well
EXEC Item_DNPK null, @.RecursionDepth
END
-- delete all items and clean up links as a result of these deletions
INSERT INTO #Temp
SELECT ME.[MimeElementKey]
FROM [dbo].[MimeElement] ME
JOIN [dbo].[Property] P
ON ME.[MimeElementKey] = P.[MimeElementKey]
WHERE P.[ItemKey] in (SELECT ItemKey FROM #Temp2 WITH (NOLOCK) WHERE
RecursionDepth = @.RecursionDepth)
IF (@.@.Error = 0)
BEGIN
DELETE [dbo].[Property]
WHERE [ItemKey] in (SELECT ItemKey FROM #Temp2 WITH (NOLOCK) WHERE
RecursionDepth = @.RecursionDepth)
END
IF (@.@.Error = 0)
BEGIN
DELETE [dbo].[MimeElement]
FROM [dbo].[MimeElement] ME
JOIN #Temp WITH (NOLOCK)
ON ME.[MimeElementKey] = #Temp.[MimeElementKey]
DELETE FROM #Temp
END
IF (@.@.Error = 0)
BEGIN
/* DELETE [dbo].[Link]
FROM [dbo].[Link] l
JOIN #Temp2 t WITH (NOLOCK) ON l.[SourceItemKey] = t.ItemKey
WHERE RecursionDepth = @.RecursionDepth
END
IF (@.@.Error = 0)
BEGIN
DELETE [dbo].[Link]
FROM [dbo].[Link] l
JOIN #Temp2 t WITH (NOLOCK) ON l.[TargetItemKey] = t.ItemKey
WHERE RecursionDepth = @.RecursionDepth */
DELETE [dbo].[Link]
WHERE [SourceItemKey] in (SELECT ItemKey FROM #Temp2 WITH (NOLOCK) WHERE
RecursionDepth = @.RecursionDepth)
OR [TargetItemKey] in (SELECT ItemKey FROM #Temp2 WITH (NOLOCK) WHERE
RecursionDepth = @.RecursionDepth)
END
IF (@.@.Error = 0)
BEGIN
UPDATE [dbo].[Property]
SET [ReferenceTargetItem] = NULL
FROM [dbo].[Property] p
JOIN #Temp2 t WITH (NOLOCK) ON p.[ReferenceTargetItem] = t.ItemKey
WHERE RecursionDepth = @.RecursionDepth
END
IF (@.@.Error = 0)
BEGIN
UPDATE [dbo].[Item]
SET [ParentKey] = NULL
FROM [dbo].[Item] i
JOIN #Temp2 t WITH (NOLOCK) ON i.[ParentKey] = t.ItemKey
WHERE RecursionDepth = @.RecursionDepth
END
IF (@.@.Error = 0)
BEGIN
DELETE [dbo].[Item]
FROM [dbo].[Item] i
JOIN #Temp2 t WITH (NOLOCK)
ON i.ItemKey = t.ItemKey
WHERE t.RecursionDepth = @.RecursionDepth
END
IF (SELECT @.RecursionDepth) = 1
BEGIN
-- delete the primary item passed in as a parameter
IF (@.@.Error = 0)
BEGIN
-- put it in #Temp2 so we can return it in the "cascadedDeletedItems"
resultset
INSERT INTO #Temp2
SELECT i.ItemKey, i.ParentKey, @.RecursionDepth
FROM [dbo].[Item] i -- WITH (NOLOCK)
WHERE i.ItemKey = @.aItemKey
exec Item_D1PK @.aItemKey
END
if (@.IsLocalTran = 1)
BEGIN
IF (@.@.Error = 0)
BEGIN
COMMIT TRAN
END
ELSE
BEGIN
ROLLBACK TRAN
END
END
SELECT @.Result = -@.@.Error
-- return the items affected by this query
SELECT distinct ItemKey FROM #Temp2
RETURN @.Result
END
END
GO
"ML" <ML@.discussions.microsoft.com> wrote in message
news:1D228D99-FB06-4FB4-AEC2-24653942A8B4@.microsoft.com...
> Comments inline:
>
> Repeatable read? Is there another reason for this isolation level? As far
> as
> I see it you could just use defaults here (READ COMMITED).
>
> The HOLDLOCK hint instructs the procedure not to release the lock until it
> ends. As I see it you select a set of values here and store them in a
> local
> temporary table, I guess you make a few changes, then update the values
> appropriately or what? Could you do these in a single update statement? It
> would really help if we could see the rest of the procedure here -
> especially
> the part where the explicit lock is acquired.
> Also try adding the ROWLOCK hint.
>
> The other procedure looks OK to me. It's a simple insert procedure, and
> has
> little or no room for improvement. I, personally, prefer the
> INSERT...SELECT
> syntax to INSERT...VALUES, but I've never heard that choosing either one
> would affect locking.
>
> ML
> --
> http://milambda.blogspot.com/|||Before I read through the entire procedure - is there a tree or a hierarchy
involved in these deletes?
This could be optimized, take a look at this example:
http://milambda.blogspot.com/2005/0...or-monkeys.html
Deletes require exclusive locks - you should make the delete procedure as
concise as possible - maybe even by building the list outside of a
transaction, and only beginning an explicit transaction just before the
actual delete statement. The delete will block other users anyway, so make i
t
as short as possible.
ML
http://milambda.blogspot.com/|||Yes. Typically an item in the item table has reference to it's parent which
is another item in the item table. The relationship from parent to children
is one to many. A row representing an item in the item table has references
to other tables that define things like properties and property types, etc.
Essentially, then, the hierarchy is to determine all the children of the
item whose id is passed in as a parameter to the sp, and recursively do that
for all those children until the end of the line is reached
I hope this answers your question.
Adrian
"ML" <ML@.discussions.microsoft.com> wrote in message
news:1DECC75A-38CD-40AB-BC63-50FD758231C9@.microsoft.com...
> Before I read through the entire procedure - is there a tree or a
> hierarchy
> involved in these deletes?
> This could be optimized, take a look at this example:
> http://milambda.blogspot.com/2005/0...or-monkeys.html
> Deletes require exclusive locks - you should make the delete procedure as
> concise as possible - maybe even by building the list outside of a
> transaction, and only beginning an explicit transaction just before the
> actual delete statement. The delete will block other users anyway, so make
> it
> as short as possible.
>
> ML
> --
> http://milambda.blogspot.com/|||That certainly is one of the function's purposes - to get a list of all
descendants in a hierarchy.
ML
http://milambda.blogspot.com/|||Thanks for the link and suggestion. I'll try putting the select outside of
the transaction and get back to you on my results
Adrian
"ML" <ML@.discussions.microsoft.com> wrote in message
news:1DECC75A-38CD-40AB-BC63-50FD758231C9@.microsoft.com...
> Before I read through the entire procedure - is there a tree or a
> hierarchy
> involved in these deletes?
> This could be optimized, take a look at this example:
> http://milambda.blogspot.com/2005/0...or-monkeys.html
> Deletes require exclusive locks - you should make the delete procedure as
> concise as possible - maybe even by building the list outside of a
> transaction, and only beginning an explicit transaction just before the
> actual delete statement. The delete will block other users anyway, so make
> it
> as short as possible.
>
> ML
> --
> http://milambda.blogspot.com/

Wednesday, March 21, 2012

Deadlock issues

I'm trying to eliminate (or at least reduce) deadlock issues. I've already
ensured all stored procedures are accessing tables in the same order and now
I am looking at locks and transaction levels. Are row level locks the
default for stored procedures in SQL Server 2000 or do I need to issue some
command to set the default to row level? Should implementing row level
locking and reducing my current transaction isolation levels from
Serializable to RepeatableRead yield any noticable difference in reducting
deadlocks? I realize this is a bit vague but I'm a VB developer tasked
with running the new SQL Server so any best practices or suggestions on this
subject are very welcome.Row level locking is the norm as long as you have proper indexes to access
the rows by. But you will definitely see more deadlocks if you are using
serializable isolation level. Read Committed is the default and should be
used where ever possible. There are very few times when you should actually
need serializable or even repeatable read isolation levels.
Andrew J. Kelly SQL MVP
"John Cobb" <john.cobb@.acxiom.com> wrote in message
news:u2oQRNPTFHA.2676@.TK2MSFTNGP10.phx.gbl...
> I'm trying to eliminate (or at least reduce) deadlock issues. I've
> already
> ensured all stored procedures are accessing tables in the same order and
> now
> I am looking at locks and transaction levels. Are row level locks the
> default for stored procedures in SQL Server 2000 or do I need to issue
> some
> command to set the default to row level? Should implementing row level
> locking and reducing my current transaction isolation levels from
> Serializable to RepeatableRead yield any noticable difference in reducting
> deadlocks? I realize this is a bit vague but I'm a VB developer tasked
> with running the new SQL Server so any best practices or suggestions on
> this
> subject are very welcome.
>
>
>|||In addition to Andrew's comment, you might want to take a look at these:
http://support.microsoft.com/kb/169960
http://support.microsoft.com/kb/224453
http://support.microsoft.com/kb/75722
-oj
"John Cobb" <john.cobb@.acxiom.com> wrote in message
news:u2oQRNPTFHA.2676@.TK2MSFTNGP10.phx.gbl...
> I'm trying to eliminate (or at least reduce) deadlock issues. I've
> already
> ensured all stored procedures are accessing tables in the same order and
> now
> I am looking at locks and transaction levels. Are row level locks the
> default for stored procedures in SQL Server 2000 or do I need to issue
> some
> command to set the default to row level? Should implementing row level
> locking and reducing my current transaction isolation levels from
> Serializable to RepeatableRead yield any noticable difference in reducting
> deadlocks? I realize this is a bit vague but I'm a VB developer tasked
> with running the new SQL Server so any best practices or suggestions on
> this
> subject are very welcome.
>
>
>|||Some of my tables have primary keys defined but not explicit indexes. Will
the PKs allow row level locking or do I explicitly need to define indexes.
Probably will do this anyway for performance but just curious.
"Andrew J. Kelly" <sqlmvpnooospam@.shadhawk.com> wrote in message
news:Osp2YVPTFHA.3176@.TK2MSFTNGP09.phx.gbl...
> Row level locking is the norm as long as you have proper indexes to access
> the rows by. But you will definitely see more deadlocks if you are using
> serializable isolation level. Read Committed is the default and should be
> used where ever possible. There are very few times when you should
actually
> need serializable or even repeatable read isolation levels.
> --
> Andrew J. Kelly SQL MVP
>
> "John Cobb" <john.cobb@.acxiom.com> wrote in message
> news:u2oQRNPTFHA.2676@.TK2MSFTNGP10.phx.gbl...
reducting
>|||PK constraints will build an index to enforce the constraint and will
function just like any other index (plus the constraint part). So they will
allow row level locking if you are using the PK in the WHERE clause as your
SARG. Rarely is the table accessed solely by the PK. You may require other
indexes to access and lock the table properly.
Andrew J. Kelly SQL MVP
"John Cobb" <john.cobb@.acxiom.com> wrote in message
news:uQ28GYAUFHA.4092@.TK2MSFTNGP12.phx.gbl...
> Some of my tables have primary keys defined but not explicit indexes. Will
> the PKs allow row level locking or do I explicitly need to define indexes.
> Probably will do this anyway for performance but just curious.
>
> "Andrew J. Kelly" <sqlmvpnooospam@.shadhawk.com> wrote in message
> news:Osp2YVPTFHA.3176@.TK2MSFTNGP09.phx.gbl...
> actually
> reducting
>sql

Friday, February 24, 2012

dbo with respect to performance

Hello Sql Gurus,
I had a discussion with my boss regarding this.
we need to have dbo at the stored procedures level
but not needed for tables with in the sp.
But I suggest to have dbo at every level at the stored procedure level
and also at the table level. which is valid.
IF EXISTS (SELECT * FROM sysobjects WHERE id = object_id('dbo.testsp'))
<<<< - - - - - - - - (Has dbo Prefix)
BEGIN
PRINT 'Dropping old version of dbo.testsp' <<<<< - - - - - - - - (Has
dbo Prefix)
DROP proc dbo.testsp <<<<< - - - - - - - - (Has dbo Prefix)
END
GO
PRINT 'Creating new version of dbo.testsp' <<<<< - - - - - - - - (Has dbo
Prefix)
PRINT ''
GO
CREATE PROC testsp <<<<< - - - - - - - - (has dbo Prefix)
AS
BEGIN
select *
from dbo.table <<<<< - - - - - - - - (has dbo Prefix)
END
GO
PRINT 'Granting privileges on dbo.testsp' <<<<< - - - - - - - - (Has dbo
Prefix)
PRINT ''
GO
revoke all on dbo.testsp from Public <<<<< - - - - - - - - (Has dbo prefix)
grant execute on dbo.testsp to public <<<<< - - - - - - - - (Has dbo prefix)
go
PRINT 'Operation Complete !'
PRINT '=======================================
========='
PRINT ''
go
Please suggest which one is correct.
Thanks & Regards
Rajesh PeddireddyYou should always specify the object owner (in SQL 2000) or the schema
name (in SQL 2005), even that owner or schema is "dbo", in every case.
Period.
In many cases statements will work without the owner/schema name but
it's a bad habit to get into. Performance is usually marginally better
(although it's usually not noticeable) using fully qualified object
names (due to simpler name resolution) but mainly it avoids ambiguity
and in some cases it's mandatory (like in indexed views for example).
It's not really a "performance" thing, but rather a "good coding" thing.
*mike hodgson*
http://sqlnerd.blogspot.com
Rajesh wrote:

>Hello Sql Gurus,
>I had a discussion with my boss regarding this.
>we need to have dbo at the stored procedures level
>but not needed for tables with in the sp.
>But I suggest to have dbo at every level at the stored procedure level
>and also at the table level. which is valid.
>IF EXISTS (SELECT * FROM sysobjects WHERE id = object_id('dbo.testsp'))
><<<< - - - - - - - - (Has dbo Prefix)
>BEGIN
> PRINT 'Dropping old version of dbo.testsp' <<<<< - - - - - - - - (Has
>dbo Prefix)
> DROP proc dbo.testsp <<<<< - - - - - - - - (Has dbo Prefix)
>END
>GO
>PRINT 'Creating new version of dbo.testsp' <<<<< - - - - - - - - (Has dbo
>Prefix)
>PRINT ''
>GO
>CREATE PROC testsp <<<<< - - - - - - - - (has dbo Prefix)
>AS
>BEGIN
> select *
> from dbo.table <<<<< - - - - - - - - (has dbo Prefix)
>
>END
>GO
>PRINT 'Granting privileges on dbo.testsp' <<<<< - - - - - - - - (Has dbo
>Prefix)
>PRINT ''
>GO
>revoke all on dbo.testsp from Public <<<<< - - - - - - - - (Has dbo prefix)
>grant execute on dbo.testsp to public <<<<< - - - - - - - - (Has dbo prefix
)
>go
>PRINT 'Operation Complete !'
>PRINT '=======================================
========='
>PRINT ''
>go
>Please suggest which one is correct.
>Thanks & Regards
>Rajesh Peddireddy
>

Sunday, February 19, 2012

dbo Cannot Add Users in SQL DB

I'm using SQL 2000 and I'm the database owner. I have been running tests with stored procedures to add logins, revoke logins, add db access, revoke db access etc.

Now I can't seem to add users to the database. I've tried using 'dbo' and 'domain\my_username' but I'm denied permission to run any stored procedures to try and add myself to the db_accessadmin or sysadmin roles.

I've tried the New Database User dialog and choose <new> under login name. I browse for the user name on my domain, click OK, and I get the message 'You must be logged in as 'sa' or a member of sysadmin or securityadmin to perform this operation.'

I thought the dbo always had full permissions on his database. This doesn't make sense to me. :confused:

The only thing I can figure is my permissions have been revoked on the master db.

Can anyone help?A DBO has full permissions on his own database, but adding a login is a server level task. You need to have the administrator add new logins for you, or be added to the securityadmin server role. You can, of course, add other logins that already exist as users in your database. You just can't create new logins.|||Oh and I'm using NT authentication.

I forgot to add that I have always been able to create logins until now by browsing for the user on our network. I was also able to create databases on the SQL Server before now. Now the option to create a new db is grayed out on the menu.

I can remove users (except in master) and delete databases but can't add users or create databases anymore.

There's no way anyone else would have changed my permissions. It had to have something to do with the stored procedures I ran yesterday. So it seems if I could revoke my permissions then there would be some way for me to re-grant them.

Would the 'sa' account be the admin for the server? I assume that would be the person that installed the SQL Server Application on our physical server. Would the only way to get my permissions back be to have him login under the 'sa' account and grant me permissions again?|||Not necessarily, but you may be lucky if the server was setup for Mixed Atuhentication. You may be out of luck if it is for Windows Authentication only. But even this can be fixed if you all were doing master backup. In this case restoring master to the time before you "ran those stored procedures" would fix the problem.