Why is SELECT creating an uncommitted transaction in SQL Server? - sql

I have disabled autocommit in SSMS.
I have been playing around with it today and after some bizarre (to me, anyway) behaviour narrowed the use case to the following:
connect to db
open a new a query (ctrl n)
issue a simple SELECT statement eg
select TOP (5) * from AdventureWorks2017.Person.Person
close the window
I get the following message in a dialog (dialogue, hmm) box:
There are uncommitted transactions. Do you wish to commit these transactions before closing the window?
Being a long-time Oracle user, I was aware there are differences in locking between Oracle and SS, but selects causing an outstanding transaction that needs to be committed or rolled back? Really? This can't be so, surely. No data has changed. Please could somebody explain? Thanks in advance.

When you're working with the console, it automatically puts your queries into a transaction. Because you haven't closed the transaction it automatically started when you started running queries of any kind, you still have a transaction open.
This MSDN article talks a bit about it.
https://learn.microsoft.com/en-us/sql/t-sql/statements/set-implicit-transactions-transact-sql

Related

Unable to resolve issue 'You can only specify the READPAST lock in the READ COMMITTED or REPEATABLE READ isolation levels'

Our client is facing this issue after launching a screen. This screen, on launching, fires a query having READPAST as table hint. This screen used to work without any error but it suddenly started throwing this issue on client side. But we are not able to reproduce this issue on our environment. We haven't released any code change, still our client started facing this issue suddenly. Can anyone help me with this issue?
Is this issue occurring due to any Microsoft update / SQL server update or any other system change?
The error clearly indicates that you are in an isolation level other than the 2 supported isolation levels as stated in the error messages.
You may try using the sys.dm_exec_sessions DMV to get the connection's isolation level.
Another way would be to use Profiler, SQL Trace or Extended Events. If you have no past experience with these tools then using Profiler would be simplest. If you do use Profiler see if you are able filter your trace on a columns such as the ApplicationName, HostName, LoginName etc. in order not to capture too much data (assuming the system is busy).
This happen due to replication in database server, Check the solution in my answer here
https://stackoverflow.com/a/67345478/1594274
Thanks

Inserted data is not shown in Oracle db using a direct query

I was not able to find a solution for this question online, so I hope I can find help here.
I've inherited a Java web application that performs changes to an Oracle database and displays data from it. The application uses a 'pamsdb' user ID. The application inserted a new row in the one of the tables (TTECHNOLOGY). When the application later queries the db, the result set includes the new row (I can see it in print outs and in the application screens).
However, when I query the database directly using sqldeveloper (using the same user id 'pamsdb'), I do not see the new row in the modified table.
A couple of notes:
1) I read here and in other locations that all INSERT operations should be followed by a COMMIT, otherwise other users cannot see the changes. The Java application does not do COMMIT, which I thought could be the source of the problem, but since I'm using the same user ID in sqldeveloper, I'm surprised I can't see the changes there.
2) I tried doing COMMIT WORK from sqldeveloper, but it didn't change my situation.
Can anyone suggest what's causing the discrepancy and how can it be resolved?
Thanks in advance!
You're using the same user, but in a different session. Once session can't see uncommitted changes made in another session, for any user - they are independent.
You have to commit from the session that did the insert - i.e. your Java code has to commit for its changes to be visible anywhere else. You can't make the Java session's changes commit from elsewhere, and committing from SQL Developer - even as the same user - only commits any changes made in that session.
You can read more about connections and sessions, and transactions, and the commit documentation summarises as:
Use the COMMIT statement to end your current transaction and make permanent all changes performed in the transaction. A transaction is a sequence of SQL statements that Oracle Database treats as a single unit. This statement also erases all savepoints in the transaction and releases transaction locks.
Until you commit a transaction:
You can see any changes you have made during the transaction by querying the modified tables, but other users cannot see the changes. After you commit the transaction, the changes are visible to other users' statements that execute after the commit.
You can roll back (undo) any changes made during the transaction with the ROLLBACK statement (see ROLLBACK).
The "other users cannot see the changes" really means other user sessions.
If the changes are being committed and are visible from a new session via your Java code (after the web application and/or its connection pool have been restarted), but are still not visible from SQL Developer; or changes made directly in SQL Developer (and committed there) are not visible to the Java session - then the changes are being made either in different databases, or in different schemas for the same database, or (less likely) are being hidden by VPD. That should be obvious from the connection settings being used by the two sessions.
From comments it seems that was the issue here, with the Java web application and SQL Developer accessing different schemas which both had the same tables.

Deadlock in SQL Server 2008 | INSERT (from application, EF) & SELECT (from stored procedure) statement working simultaneously

Program to insert into my 2 tables is written through Entity Framework and to SELECT the data is through a STORED PROC at SQL SERVER level. There is a point when SELECT and INSERT is getting done at the same time simultaneously. And when hitting that point, I got the below error:
Transaction (Process ID) was deadlocked on resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
How can I get rid of this DEADLOCK problem here? Need the best way to solve it.
Option 1: Implementing NOLOCK? What would be the PROS and CONS here for it?
Option 2: IF there is any way to exceed the DEADLOCK wait time so that it can wait for the resource for a longer time than usually it does? If yes, then HOW?
Option 3: Suggest Me?
Thanks,
Rahuul Dutta
A deadlock cannot be cured by increasing lock timeout. The resources are locked in such a way that it cannot be resolved by itself, regardless of how much time you can give it. A special background process in SQL Server, a deadlock monitor, periodically (rather often, actually) runs and if it identifies a deadlock it kills the 'lighter' transaction immediatelly.
The deadlocks are usually dealt with in one of several ways: by providing an alternative data access path for the SELECT query (ie adding a mnnclustered index), minimizing the transaction duration (by better indexing, again), or using one of snapshot isolation levels.
The least effort solution here will be setting the read committed snapshot isolation level. This way the SELECT query will not issue any shared locks on data, but still read only the committed data, which is a huge plus over using the NOLOCK hint (or read uncommitted isolation level).
You can change your transaction isolation level. Best option for deadlocks would be snapshot isolation i think. If you cannot turn this option on in your server or if you run into I/O issues, read committed should still prevent deadlocks from read/write dependencies. Make sure that you don't run into anomalies, read committed will allow non-repeatable reads and phantom reads.
First of all, thanks a lot for your precious answers!
With the help of your answers, some research and a call with Microsoft DBA team, I have got the following solution.
Solution: To implement this solution we have to change the database property to Read Committed Snapshot. This will help the Select statements in avoiding the blocks in case of locks by other sessions on the same table.
- To cater this solution the database will create a snapshot of the data in tempdb. Therefore we must have sufficient space in tempdb. Also if possible we must shift the tempdb to a new disk to split the I/O. This will improve the performance.
The following kb article helps in enabling Read Committed Snapshot property of the database:
http://technet.microsoft.com/en-us/library/ms175095(v=SQL.105).aspx
Alternately we can change this property through SSMS by right clicking the database---options---Miscellaneous----Is Read Committed Snapshot On. We have to change the value of this property to TRUE.
We do not have to restart the server to enable this property however we must note that 'When setting the READ_COMMITTED_SNAPSHOT option, only the connection executing the ALTER DATABASE command is allowed in the database. There must be no other open connection in the database until ALTER DATABASE is complete. The database does not have to be in single-user mode.'
This means we need a small amount of downtime from the application side.
Hope the MOM above would help you all too. :)
Thanks,
Rahuul Dutta

Force a Transaction to commit from another connection?

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

Transaction Locked Down SQL Server 2005

I have noticed something over the last few months. Each time we run a script that has a transaction statements let say we stop the query unexpectedly this action actually lock the database.
The only way out is to destroy the transaction each time. I have never experience this before even though I have stopped the query in the middle of transaction in the past and it has never locked the database.
Could it be that we are missing something in settings or I should not stop transaction queries unexpectedly?
The problem occurred with SQL SERVER 2005. please I need your brain. Thanks Guys
This is usual: you have sent a client abort which say "stop processing"
To rollback and release lock, you need to use SET XACT_ABORT ON
SO 1 and SO 2