How do you set autocommit in an SQL Server session? - sql-server

How do you set autocommit in an SQL Server session?

You can turn autocommit ON by setting implicit_transactions OFF:
SET IMPLICIT_TRANSACTIONS OFF
When the setting is ON, it returns to implicit transaction mode. In implicit transaction mode, every change you make starts a transactions which you have to commit manually.
Maybe an example is clearer. This will write a change to the database:
SET IMPLICIT_TRANSACTIONS ON
UPDATE MyTable SET MyField = 1 WHERE MyId = 1
COMMIT TRANSACTION
This will not write a change to the database:
SET IMPLICIT_TRANSACTIONS ON
UPDATE MyTable SET MyField = 1 WHERE MyId = 1
ROLLBACK TRANSACTION
The following example will update a row, and then complain that there's no transaction to commit:
SET IMPLICIT_TRANSACTIONS OFF
UPDATE MyTable SET MyField = 1 WHERE MyId = 1
ROLLBACK TRANSACTION
Like Mitch Wheat said, autocommit is the default for Sql Server 2000 and up.

I wanted a more permanent and quicker way. Because I tend to forget to add extra lines before writing my actual Update/Insert queries.
I did it by checking SET IMPLICIT_TRANSACTIONS check-box from Options.
To navigate to Options Select Tools>Options>Query Execution>SQL Server>ANSI in your Microsoft SQL Server Management Studio.
Just make sure to execute commit or rollback after you are done executing your queries. Otherwise, the table you would have run the query will be locked for others.

Autocommit is SQL Server's default transaction management mode. (SQL 2000 onwards)
Ref: Autocommit Transactions

With SQLServer 2005 Express, what I found was that even with autocommit off, insertions into a Db table were committed without my actually issuing a commit command from the Management Studio session. The only difference was, when autocommit was off, I could roll back all the insertions; with *autocommit on, I could not.*
Actually, I was wrong. With autocommit mode off, I see the changes only in the QA (Query Analyzer) window from which the commands were issued. If I popped a new QA (Query Analyzer) window, I do not see the changes made by the first window (session), i.e. they are NOT committed! I had to issue explicit commit or rollback commands to make changes visible to other sessions(QA windows) -- my bad! Things are working correctly.

Related

Undo insert query in SQL Server

I ran an insert query on a table in SQL Server by mistake and 100 rows got inserted. I want to undo it but I do not have rollback.
You can only delete, but for future you would need to surround your query in transaction or set such behavior manually.
By default SSMS does auto-commit. To alter this behavior use this:
SET IMPLICIT_TRANSACTIONS OFF
more here:
https://learn.microsoft.com/en-us/sql/t-sql/statements/set-implicit-transactions-transact-sql?view=sql-server-ver15

Use of transaction in MSSQL, update several tables

I need a sanity check ;[, a customer of mine says he is seeing data at a time when I think he should not.
example, update 2 tables
BEGIN TRANSACTION;
update table1...
update table2...
COMMIT TRANSACTION;
question - it is possible for a separate connection in the database to be triggered to read the updates to table1 before the updates in table2 are done?
Yes you can if you set the isolation level of the other reading transaction to read uncommited. https://msdn.microsoft.com/en-us/library/ms173763(v=sql.110).aspx.
It's easy to test if you start up two Sql Management Studios and run the transaction without commiting in one window, then try to select in the other window with different Isolation Levels.
Yes, it is possible, if your isolation level is set to read uncommitted.
Look at the isolation level provided by:
dbcc useroptions
https://msdn.microsoft.com/en-us/library/ms173763.aspx
http://blog.sqlauthority.com/2010/05/24/sql-server-check-the-isolation-level-with-dbcc-useroptions/

DDL commands are AutoCommit in SQL server, what does it mean?

at most pages I have read that "DDL commands have AutoCommit in SQL Server", if I am not wrong this statement simply means that we don't need explicit commit command for DDL commands.
then why...
1) Alter TABLE EMP Add Age INT;
UPDATE EMP SET Age=20;
fails ,saying Invalid column name 'Age'
2) BEGIN TRAN
Alter TABLE EMP Add Age INT;
ROLLBACK
can be rollbacked successfully.
Maybe I am wrong with concept of AutoCommit, please explain it with example where it actully has effects.
Thanks for any help.
Autocommit Transactions:
A connection to an instance of the Database Engine operates in autocommit mode until a BEGIN TRANSACTION statement starts...
So, your second example doesn't apply. Further down:
In autocommit mode, it sometimes appears as if an instance of the Database Engine has rolled back an entire batch instead of just one SQL statement. This happens if the error encountered is a compile error, not a run-time error. A compile error prevents the Database Engine from building an execution plan, so nothing in the batch is executed.
Which is what your first example deals with.
So, neither one is actually dealing with Autocommit transactions.
So, lets take a statement like:
Alter TABLE EMP Add Age INT;
If you have an open connection in Autocommit mode, execute the above, and it completes without errors, then you will find that this connection has no open transactions, and the changes are visible to any other connection immediately.
If you have an open connection in Implicit Transactions mode, execute the above, and it completes without errors, then you will find that this connection has an open transaction. Other connections will be blocked on any operations that require a schema lock on EMP, until you execute either COMMIT or ROLLBACK.
If you have an open connection, in which you have executed BEGIN TRANSACTION, execute the above, and it completes without errors - then you'll be in the same situation as for Implicit Transactions. However, having COMMITed or ROLLBACKed, your connection will revert to either Autocommit mode or Implicit Transactions mode (whichever was active before the call to BEGIN TRANSACTION).
If you have a begin tran explicitly like in your second example, then you have to commit it. (you can roll back as well)
If you dont specify it explicity like in your first example then it is autocommit.
autocommit is the default mode in sql server, which can be turned off if requried
If you add batch in your code it will work
Alter TABLE EMP Add Age INT;
go
UPDATE EMP SET Age=20;

Do DB locks require transactions?

Is it true that "Every statement (select/insert/delete/update) has an isolation level regardless of transactions"?
I have a scenario in which I have set update of statements inside a transaction (ReadCommitted).
And another set not in a transaction (select statements).
In this case when first set is executing another waits.
If I set READ_COMMITTED_SNAPSHOT for DB Deadlock occurs.
ALTER DATABASE Amelio SET ALLOW_SNAPSHOT_ISOLATION ON
ALTER DATABASE Amelio SET READ_COMMITTED_SNAPSHOT ON
To solve this problem, do I need to put "Select" statements in TransactionScope?
On SQL Server every transaction has an implicit or explicit transaction level. Explicit if called with BEGIN/COMMIT/ROLLBACK TRANSACTION, implicit if nothing like this is issued.
Start your snapshot before the update query starts. Otherwise you give SQL Server no chance to prepare the changed rows into tempdb and the Update query still has the lock open.
Another way without creating a snapshot isolation is to use SELECT <columns> FROM <table> WITH (NOLOCK) which is the way to tell SQL Server to get the rows no matter what (aka READ_UNCOMMITED). As it is a query hint it changes the isolation level even with your settings. Can work if you are not bothered which state of the row is queried - however caution needs to be used when evaluating the data received.

How long should SET READ_COMMITTED_SNAPSHOT ON take?

How long should it take to run
ALTER DATABASE [MySite] SET READ_COMMITTED_SNAPSHOT ON
I just ran it and it's taken 10 minutes.
How can I check if it is applied?
You can check the status of the READ_COMMITTED_SNAPSHOT setting using the sys.databases view. Check the value of the is_read_committed_snapshot_on column. Already asked and answered.
As for the duration, Books Online states that there can't be any other connections to the database when this takes place, but it doesn't require single-user mode. So you may be blocked by other active connections. Run sp_who (or sp_who2) to see what else is connected to that database.
Try this:
ALTER DATABASE generic SET READ_COMMITTED_SNAPSHOT ON WITH ROLLBACK IMMEDIATE
OK (I am the original questioner) so it turns out this whole time I didn't even have the darn thing enabled.
Here's the ultimate code to run to enable snapshot mode and make sure it is enabled.
SELECT is_read_committed_snapshot_on, snapshot_isolation_state_desc,snapshot_isolation_state FROM sys.databases WHERE name='shipperdb'
ALTER DATABASE shipperdb SET allow_snapshot_isolation ON
ALTER DATABASE shipperdb SET SINGLE_USER WITH ROLLBACK IMMEDIATE
ALTER DATABASE shipperdb SET read_committed_snapshot ON
ALTER DATABASE shipperdb SET MULTI_USER
SELECT is_read_committed_snapshot_on, snapshot_isolation_state_desc,snapshot_isolation_state FROM sys.databases WHERE name='shipperdb'
This works even with connections active (presumably you're fine with them getting kicked out).
You can see the before and after state and this should run almost immediately.
IMPORTANT:
The option READ_COMMITTED_SNAPSHOT above corresponds to IsolationLevel.ReadCommitted in .NET
The option ALLOW_SNAPSHOT_ISOLATION above corresponds to IsolationLevel.Snapshot in .NET
Great article about different versioning
.NET Tips:
Looks like Isolationlevel.ReadCommitted is allowed in code even if not enabled by the database. No warning is thrown. So do yourself a favor and be sure it is turned on before you assume it is for 3 years like I did!!!
If you're using C# you probably want the ReadCommitted IsolationLevel and not Snapshot - unless you are doing writes in this transaction.
READ COMMITTED SNAPSHOT does optimistic reads and pessimistic writes. In contrast, SNAPSHOT does optimistic reads and optimistic writes. (from here)
bool snapshotEnabled = true;
using (var t = new TransactionScope(TransactionScopeOption.Required,
new TransactionOptions
{
IsolationLevel = IsolationLevel.ReadCommitted
}))
{
using (var shipDB = new ShipperDBDataContext())
{
}
}
In additional you may get an error about being 'unable to promote' a transaction. Search for 'promotion' in Introducing System.Transactions in the .NET Framework 2.0.
Unless you're doing something special like connecting to an external database (or second database) then something as simple as creating a new DataContext can cause this. I had a cache that 'spun up' its own datacontext at initialization and this was trying to escalate the transaction to a full distributed one.
The solution was simple :
using (var tran = new TransactionScope(TransactionScopeOption.Suppress))
{
using (var shipDB = new ShipperDBDataContext())
{
// initialize cache
}
}
See also Deadlocked article by #CodingHorror
Try this code:
if(charindex('Microsoft SQL Server 2005',##version) > 0)
begin
declare #sql varchar(8000)
select #sql = '
ALTER DATABASE ' + DB_NAME() + ' SET SINGLE_USER WITH ROLLBACK IMMEDIATE ;
ALTER DATABASE ' + DB_NAME() + ' SET READ_COMMITTED_SNAPSHOT ON;
ALTER DATABASE ' + DB_NAME() + ' SET MULTI_USER;'
Exec(#sql)
end
I tried the command:
ALTER DATABASE MyDB SET READ_COMMITTED_SNAPSHOT ON
GO
against a dev box but the it took 10+ minutes and so I killed it.
I then found this:
https://willwarren.com/2015/10/12/sql-server-read-committed-snapshot/
and used his code block (which took about 1:26 to run):
USE master
GO
/**
* Cut off live connections
* This will roll back any open transactions after 30 seconds and
* restricts access to the DB to logins with sysadmin, dbcreator or
* db_owner roles
*/
ALTER DATABASE MyDB SET RESTRICTED_USER WITH ROLLBACK AFTER 30 SECONDS
GO
-- Enable RCSI for MyDB
ALTER DATABASE MyDB SET READ_COMMITTED_SNAPSHOT ON
GO
-- Allow connections to be established once again
ALTER DATABASE MyDB SET MULTI_USER
GO
-- Check the status afterwards to make sure it worked
SELECT is_read_committed_snapshot_on
FROM sys.databases
WHERE [name] = 'MyDB '
Try use master database before altering current database.
USE Master
GO
ALTER DATABASE [YourDatabase] SET READ_COMMITTED_SNAPSHOT ON
GO
I didn't take a second for me when i changed my DB to single user
All you need to do is this:
ALTER DATABASE xyz SET READ_COMMITTED_SNAPSHOT ON WITH ROLLBACK IMMEDIATE;
No need to put the database into single user mode.
You will rollback uncommitted transactions though.
Try Shut off the other SQL services so that only the SQL server service is running.
Mine ran for 5 minutes then I cancelled it because it was obvious nothing was happening. Its a brand new server so there are no other users connected. I shut off the SQL Reporting Services and then ran it again.. took less than a second to complete.
With "ROLLBACK IMMEDIATE" it took about 20-30 seconds on my db which is 300GB.
ALTER DATABASE DBNAME SET READ_COMMITTED_SNAPSHOT ON WITH ROLLBACK IMMEDIATE

Resources