There is lock on the table which persists the disconnection - sql-server

I have a very small table in my database with only one row in it. When I do select statement on it, my query always times out. I have tried following things:
Conecting/disconnecting from the database server
doing select * from table(nolock)- which works fine and also proves that there is some lock on the table
However, How can I remove the lock from the table and how can I know what is holding the table captive? Also, I am not sure how does this lock survive the disconnection from the database server?

Related

Does oracle allow Select on table when whole table is locked by delete sql

When oracle executes a delete sql(with no where clause), it locks the whole table. So while the data is getting deleted from a table by a particular user session and if during that time period, will oracle allow any other user sessions to read data from the same table as the table is being locked?
delete from tran_records;
Will there be any difference in behaviour for the above scenario in optimistic and pessimistic locking?
Readers are never (b)locked, so - yes, select will work, that user will see all data in the table UNTIL delete operation is committed. Then nobody will see anything as there'll be no data in the table (not talking about flashback here).

TABLOCKX not working

I am playing with my SQL Server 2012 trying to get a hold of the locks. Based on a tutorial I saw, I tried to test obtaining an exclusive lock on a table so that no other query would be able to read information from it, until the transaction is not over, but its just not working. Even though it was working in the video, here is my query in the first window :
use TSQL2012
BEGIN transaction
update tele with (TABLOCKX, holdlock)
set cor = '12'
waitfor delay '00:05'
go
then in a second query window I simply tried:
select * from tele
and it worked fine, although on theory there should have been "exclusive" lock preventing that. Why is that happening? I tried also with
set transaction isolation level serializable on
and also without the delay but the select is always successful. Any ideas?
I've tried this on two different tables and can easily reproduce what you've found. Here is what is happening:
If Sql-Server is returning rows to the SELECT query before the table is updated then its VERY probable that at that moment, there are already locks on your tele table that are incompatible with an exclusive lock. For example, if there is another session somewhere that already has a reader lock on the table then your UPDATE statement will be SUSPENDED with a WAIT_TYPE of LCK_M_X, meaning that your UPDATE is blocked, waiting for locks that are incompatible with an exclusive lock to be released. Since all locks are incompatible with an exclusive table lock then when any other session is accessing the table with any kind of lock, your update statement will be suspended.
In a 3rd instance of SQL Management Studio, right click your server and open activity monitor. Filter for your database and login and re-run the experiment. If the table is something that applications use frequently and the SELECT runs before the UPDATE, then you will notice a LCK_M_X WAIT_TYPE on the UPDATE.
Try creating a new table that only you know about and re-run the experiment. It should work.

Sql Server rows being auto inserted without a trigger

I have a table in sql server, for which, if I delete a row from it, a new row is inserted with the same data, and userid as the one I deleted. There are no triggers on this table. In addition, I did a search of all database objects that reference this table, and there are no triggers anywhere in the database that reference this table, only some stored procedures, none of which have any code that would cause this behavior.
To be clear, if I run this query:
delete from my_table where id = 1
the row with the id of 1 will be deleted, but a new row will be inserted that has the same userid, and date as the deleted row. No application code involved, just a straight sql delete statement run directly on the database causes this.
What else besides a trigger could be causing this to happen? I've never encountered something like this before.
It took me a long time, but I discovered this was being caused by a "rogue" linq-to-sql dll that was running in spite of it's parent app being killed.
The good news is, there isn't some weird non-trigger way to insert rows on delete in SQL, so we can all resume our normal lives now, knowing all is as it was.

Update deadlock issue

I'm using SQL server 2005 and running into deadlock issues. I've begun reading up on NO LOCK, but I'm not sure that is the correct way to solve my problem. Any assistance would be greatly appreciated.
I have a batch process that is running every 15 seconds. It generates dynamic UPDATE SQL statements based off a list of foreign keys. To over simplify, imagine the below simple SQL statement:
UPDATE dual
SET val1 = #val1
WHERE fk = #fk
;
Remember this example is over simplified, for each foreign key the SQL statement is actually different, but the table it updates and the values are always the same. I cannot just write a single update statement to deal with all the foreign keys at once.
If I run each statement one at a time everything works fine, but I risk going over my 15 second interval. As a silver bullet, I decided to multi thread the batch application so it would run 25 update statements at once instead of just 1 at a time. After doing this, I begin receiving deadlock errors.
How do I solve this deadlock issue? Three things to remember:
The batch is the only application that will ever INSERT, UPDATE, or
DELETE records from the table in question
Every UPDATE statement uses the foreign key in the WHERE clause, so
the batch would never access the same record at once
If a record gets bad data, the batch would self correct it in the
next run
Instead of your current setup, within your dynamic sql create a table variable and insert your values into it. This will all be inserts so you should not have to worry about deadlocks. Next update your table(s) with a single update by joining your table variable to your real table. This way you are only hitting your actual table with one single update statement.

Can adding a primary key identity column solve deadlock issues?

I have a table in SQL server that is CRUD-ed concurrently by a stored procedure running simultaneously in different sessions:
|----------------|---------|
| <some columns> | JobGUID |
|----------------|---------|
The procedure works as follows:
Generate a GUID.
Insert some records into the shared table described above, marking them with the GUID from step 1.
Perform a few updates on all records from step 2.
Select the records from step 3 as SP output.
Every select / insert / update / delete statement in the stored procedure has a WHERE JobGUID = #jobGUID clause, so the procedure works only with the records it has inserted on step 2. However, sometimes when the same stored procedure runs in parallel in different connections, deadlocks occur on the shared table. Here is the deadlock graph from SQL Server Profiler:
Lock escalations do not occur. I tried adding (UPDLOCK, ROWLOCK) locking hints to all DML statements and/or wrapping the body of the procedure in a transaction and using different isolation levels, but it did not help. Still the same RID lock on the shared table.
After that I've discovered that the shared table did not have a primary key/identity column. And once I added it, deadlocks seem to have disappeared:
alter table <SharedTable> add ID int not null identity(1, 1) primary key clustered
When I remove the primary key column, the deadlocks are back. When I add it back, I cannot reproduce the deadlock anymore.
So, the question is, is a primary key identity column really able to resolve deadlocks or is it just a coincidence?
Update: as #Catcall suggests, I've tried creating a natural clustered primary key on the existing columns (without adding an identity column), but still caught the same deadlock (of course, this time it was a key lock instead of RID lock).
The best resource (still) for deadlock resolution is here: http://blogs.msdn.com/b/bartd/archive/2006/09/09/deadlock-troubleshooting_2c00_-part-1.aspx.
Pt #4 says:
Run the queries involved in the deadlock through Database Tuning
Advisor. Plop the query in a Management Studio query window, change
db context to the correct database, right-click the query text and
select “Analyze Query in DTA”. Don’t skip this step; more than half
of the deadlock issues we see are resolved simply by adding an
appropriate index so that one of the queries runs more quickly and
with a smaller lock footprint. If DTA recommends indexes (it'll say
“Estimated Improvement: %”), create them and monitor to
see if the deadlock persists. You can select “Apply Recommendations”
from the Action drop-down menu to create the index immediately, or
save the CREATE INDEX commands as a script to create them during a
maintenance window. Be sure to tune each of the queries separately.
I know this doesn't "answer" the question to why necessarily, but it does show that adding indexes can change the execution in ways to make either the lock footprint smaller or execution time faster which can significantly reduce the chances of a deadlock.
Recently I have seen this post, according to above information i hope this post will help you,
http://databaseusergroup.blogspot.com/2013/10/deadlocked-on-sql-server.html

Resources