I'm facing some locks at our DB server created by our application. What I don't understand is how a process that is Sleeping is having an Open Transaction (that process 71 is the one creating the Lock).
As far as I know when a process finishes it closes all the opened transactions. Is that rigth?
Thanks in advance mates.
As far as I know when a process
finishes it closes all the opened
transactions. Is that right?
No. If you explicitly open a transaction you must explicitly commit or rollback. Until that time the transaction remains open so it is perfectly possible for a connection to be idle (not currently processing any task) but still have an uncommitted transaction.
Many people expect that an error will automatically roll back a transaction but this is not the case unless you have
set xact_abort on
As far as I know when a process
finishes it closes all the opened
transactions. Is that rigth?
Yes. But it is not guaranteed and you should not rely on it. You must explicitly close the connection.
Related
I have a procedure, currently running at one SPID. Now, I found the query running too slow. In this Proc update/insert going on. If I kill the session, will what happen?
SQL Server will stop executing the query and rollback any open transactions. That rollback will undo any changes that haven't been fully committed. Since SQL Server adheres to the ACID principle, you shouldn't be able to leave your database in a bad state, even by killing SPIDs. That isn't to say you couldn't leave your data in a bad state, i.e. not wrapping multiple operations in a transaction to enforce consistency upon failure.
https://msdn.microsoft.com/en-us/library/ms173730.aspx
Check the docs here. In a nutshell which ever spid you kill will be disconnected
KILL can be used to terminate a normal connection, which internally terminates the transactions that are associated with the specified session ID
We have a very difficult to track down bug in one of our software solutions that sometimes leaves an open transaction. We have this application in production at a number of sites (read: 70+), and we've only seen this issue twice so far this year at separate locations.
The issue we're having is a transaction that's being left open from the constant connection to the SQL Server. Using dbcc opentran shows that there is a single transaction left open. In today's case, it was open from 9:30 AM before we realized it at 1:00 PM. Closing the program with the connection will result in the transaction being closed/cancelled, and all the data from the day thus far lost.
Using dbcc opentran it responds with the name of the open transaction was user_transaction. Trying to close it with commit tran user_transaction gives an error of The COMMIT TRANSACTION request has no corresponding BEGIN TRANSACTION..
I can understand you would almost never want to force the transaction to be committed without the prior connection's knowledge, but is there any way to do so? In this case, we closed the program and we lost a half of day's business worth of data.
Thanks.
If it were possible for a transaction to be committed by another conenction, then it's not a transaction. If this were possible, it would open the door to way more issues than it would solve.
See this link: http://ask.sqlservercentral.com/questions/3865/forcing-a-transaction-to-commit.html
I find many sleeping process my SQL Server database and looks like one of those sleeping SPIDs is blocking another process, and that process is getting suspended too...
Could some one please explain this...
1.) How can a sleeping process block another process?
2.) I see many sleeping process...is this normal?
Thanks
Locks are held for various durations, but the most common blocking locks, the X locks, are held for the duration of the transaction. Since transaction lifetime is completely unrelated to batch lifetime, it is absolutely normal to have a sleeping SPID to own locks, it simply means the client has started a transaction and executed some updates. As soon as the client decides to continue and issues a command to the server to commit or rollback the transaction, the blocking will be gone.
Other frequent locking is database session lock, which is a shared lock held by a connection using a database. The simple act of maintaining the connection will hold the lock, but usually this only conflict with operations that try to acquire an X lock on the database, like ALTER DATABASE DDL.
There are more esoteric cases, like two-phase-commit locks held after recovery, but those are probably not your problems. What you're seeing is most likely one of the trivial cases of an user that runs something from SSMS and forgets to commit, or an application that holds long transactions, perhaps is even leaking them.
1.) How can a sleeping process block another process?
A sleeping process is waiting for work. Double check if there's really a sleeping process blocking something, because that's really unlikely.
2.) I see many sleeping process...is this normal?
Many sleeping processes is perfectly normal. For example, the connection pool from a single web server usually keeps 10 processes open. This is great for performance.
Here is a list of process states:
Status Meaning
---------------------------------------------------------------------------------
Background The SPID is running a background task, such as deadlock detection.
Sleeping The SPID is not currently executing. This usually indicates that the
SPID is awaiting a command from the application.
Running The SPID is currently running on a scheduler.
Runnable The SPID is in the runnable queue of a scheduler and waiting to get
scheduler time.
Sos_scheduler_yield The SPID was running, but it has voluntarily yielded its
time slice on the scheduler to allow another SPID to acquire
scheduler time.
Suspended The SPID is waiting for an event, such as a lock or a latch.
Rollback The SPID is in rollback of a transaction.
Defwakeup Indicates that the SPID is waiting for a resource that is in the
process of being freed. The waitresource field should indicate the
resource in question.
Is the sleeping process waiting for user input (such as a web application)? We had this problem today with a web app which was leaving a transaction open after finishing a request. Then it just sat there waiting for the next request while it had the database locked.
We have now fixed the issue, and here are two things I can advise you to check in your SQL code:
(1) Make sure that all of your BEGIN TRANSACTION statements have a corresponding COMMIT TRANSACTION at the end. Otherwise your app might incorrectly hold a transaction open while waiting for the next user request.
(2) Check all uses of THROW to see whether any THROW statements are inside of a transaction. If you want to throw an error during a transaction, you first have to ROLLBACK TRANSACTION before the THROW, or else SQL Server will leave the transaction open and the database locked.
Are they rolled back immediately?
Are they rolled back after some period of time?
Are they left in an uncommitted state?
Is the behavior the same if connection pooling is used and the connections are simply reset?
It can stay open while connection pooling applies. Example: command timeout can leave locks and TXN because the client sends as "abort".
2 solutions:
Test in the client, literally:
IF ##TRANCOUNT <> 0 ROLLBACK TRAN
Use SET XACT_ABORT ON to ensured a TXN is cleaned up: Question 1 and Question 2
I always use SET XACT_ABORT ON.
From this SQL Team blog:
Note that with connection pooling,
simply closing the connection without
a rollback will only return the
connection to the pool and the
transaction will remain open until
later reused or removed from the pool.
This can result in locks begin held
unnecessary and cause other timeouts
and rolling block
From MSDN, section "Transaction Support" (my bold)
When a connection is closed, it is
released back into the pool and into
the appropriate subdivision based on
its transaction context. Therefore,
you can close the connection without
generating an error, even though a
distributed transaction is still
pending. This allows you to commit or
abort the distributed transaction at a
later time.
Uncommitted changes are not visible outside of the connection, so the time of the rollback is irrelevant. So yes, the transaction is eventually rolled back.
The server will rollback immedeatly any uncommited transaction when a session is closed.
The ADO pool is reponsible for clearing any uncommited transaction before returning a transaction to the pool. If you dispose a connection with pending transactions, it will rollback.
Transactions can be started by the client using the ADO API (SqlConnection.BeginTransaction) or by executing an BEGIN TRANSACTION statement. The TDS protocol between client and server has special tokens informing the client when a transaction was started/commited like this so ADO knows that the connection has pending transactions even if they are started in T-SQL code.
Can someone tell me what the statuses mean in SQL Server's sp_who command? Why might a spid be suspended? What does it mean to be "runnable"?
Thanks!
Pretty easy to find answer online. Link
dormant. SQL Server is resetting the session.
running. The session is running one or more batches. When Multiple Active Result Sets (MARS) is enabled, a session can run multiple batches. For more information, see Using Multiple Active Result Sets (MARS).
background. The session is running a background task, such as deadlock detection.
rollback. The session has a transaction rollback in process.
pending. The session is waiting for a worker thread to become available.
runnable. The session's task is in the runnable queue of a scheduler while waiting to get a time quantum.
spinloop. The session's task is waiting for a spinlock to become free.
suspended. The session is waiting for an event, such as I/O, to complete.
I believe that part of the confusion on this is that there are statuses outside of the list shown above that are seen. Three that come to mind are
Sleeping
Awaiting Command
Other