Critical section in query SQL Server stored procedure - locking

I have a stored procedure and I want to run it once at the same time.
In the other hand Like lock variable in C# programing.
Can anyone help me?

for this situation you can use 2 solution for your critical section and the block you want to only one time a time
First use SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
For example
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
begin Tran
your Query
Commit Tran
Second Use DeadLock priority normal
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
begin Tran
your Query
Commit Tran

Related

How to create transaction with isolation level in SQL

How to create a transaction with isolation level in SQL.
I'v tried something like this, but obviously it does not work:
INSERT INTO test(col1) VALUES ('test')
SET TRANSACTION ISOLATION LEVEL read stability;
COMMIT WORK;
I'm using SQL DB2 LUW
https://www.ibm.com/docs/en/db2/11.5?topic=information-sqlj-set-transaction-clause says:
You can execute SET TRANSACTION only at the beginning of a transaction.
https://www.ibm.com/docs/en/i/7.5?topic=statements-set-transaction says:
The SET TRANSACTION statement can only be executed when it is the
first SQL statement in a unit of work, unless:
all previous statements executed in the unit of work are SET
TRANSACTION statements or statements that are executed under isolation
level NC, or
it is executed in a trigger.
I'm not a user of DB2, but this seems to say that you must SET TRANSACTION before your INSERT. This matches my experience in other RDBMS products.
Look at the SET CURRENT ISOLATION statement.

Update inside a read uncommitted transaction

I am having an SP with transaction isolation level set as Read Uncommitted.
For Example
Create Procedure TrailSP
AS
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
BEGIN TRY
UPDATE TrialTable
SET TrailColumn ='Update'
WHERE TrailID=1
--this is followed by more updates and selects
END TRY
BEGIN CATCH
RETURN -1;
END CATCH
RETURN 0;
what I want to know is that the first update I have given in the SP will it get committed instantly as it executes or will it get committed along with the rest of the logic at the end of Sp.
It will get committed, as any update under any transaction isolation level, when the transaction commits. This has nothing to do with the stored procedure ending.
If the call to your procedure has a transaction, then the commit will occur when that transaction commits.
If the call to your procedure does not have a transaction but the session has enabled implicit transactions then it will commit when the application explicitly commits.
If the call to your procedure does not have a transaction and session has the auto commit transaction behavior (ie. the most common case) then transaction will commit when the UPDATE statement completes.
Enabling READ UNCOMMITTED for an UPDATE is a no-op.
-Any data read inside a READ UNCOMMITTED is data that could disappear because the transaction that wrote it rollback.
-Its also possible to not see some row that have been committed because a transaction that have not yet committed and might never commit deleted it.
-Its also possible for row to be missing or be duplicated because of PageSplit.
Basically anything is possible, so the data read should never be used to compute anything that should be written to the database or you risk corrupting your database.
TLDR: never use READ UNCOMMITTED

Transaction isolation for sql statements

Can we set isolation level for plain SQL statements in a stored procedure in SQL Server 2005/2008?
Case 1: (This will work fine)
CREATE PROCEDURE MySP
AS
BEGIN
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
BEGIN TRAN
SELECT * FROM MyTable
COMMIT TRAN
END
Case 2: (does this isolation stuff work here?)
CREATE PROCEDURE MySP
AS
BEGIN
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT * FROM MyTable
END
If case 2 is correct, would it work for several select statements as well?
Yes it will work for multiple select statements.
If you are worried about the lack if a transaction in the second stored procedure you should know that the query is executed under an implicit transaction as opposed to an explicit transaction that you have in the first stored procedure.
If you use SET TRANSACTION ISOLATION LEVEL in a stored procedure, this transaction isolation level is used for the duration of the stored proc. According to MSDN:
If you issue SET TRANSACTION ISOLATION LEVEL in a stored procedure or trigger, when the object returns control the isolation level is reset to the level in effect when the object was invoked.
Setting transaction isolation level is not the same as starting a transaction. Transaction isolation level tells SQL Server how to control locking.
If you only have multiple SELECT queries with READ UNCOMMITTED transaction isolation level, putting them all into a transaction won't make practical difference.
Isolation level can be set either at the session level with a session option or at the query level with a table hint. To set isolation level of the whole session we use command:
SET TRANSACTION ISOLATION LEVEL <isolation name>;
You can use a table hint to set the isolation level of a query as:
SELECT ... FROM <table> WITH (<isolationname>);
so in your case it would be like:
SELECT *
FROM MyTable WITH (READCOMMITTEDLOCK);
One thing here to note is: with the session option a space is specified between the words in case the name of the isolation level is made of more than one word, such as REPEATABLE READ. With the query hint,we don’t specify a space between the words—for example, WITH (REPEATABLEREAD).

SQL Server: how to set default isolation level for the entire stored procedure?

If right after BEGIN I have SET TRANSACTION ISOLATION LEVEL ... statement, will the given transaction level in force for the entire scope of the stored procedure regardless if I use BEGIN TRANSACTION or not? Namely if I have simple SELECT statements, which are atomic/transacted by definition, will the default transaction level for them set to the given one?
BEGIN
SET TRANSACTION ISOLATION LEVEL READ COMMITTED
-- will a transaction level for a atomic transaction created by SQL Server for this statement be READ COMMITTED
SELECT * FROM T
END
First, the default isolation level in SQL Server is Read Committed, so that statement doesn't really do anything unless you've changed the default isolation level.
But, in general, yes, SET Transaction Isolation Level will change the isolation level for the whole procedure (the duration of the connection, in fact)
Keep in mind that all SQL statements are implicit transactions meaning that if, for example, an update fails 99% through, it will rollback automatically; no BEGIN TRAN/COMMIT is necessary.
To answer your question, yes, your SELECT statements will inherit the isolation level you set (or the default if you do not set one) unless you override the behavior with a query hint like WITH NOLOCK which will make the individual query behave as though you did SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

SQL Server: serializable level not working

I have the following SP:
CREATE PROCEDURE [dbo].[sp_LockReader]
AS
BEGIN
SET NOCOUNT ON;
begin try
set transaction isolation level serializable
begin tran
select * from teste
commit tran
end try
begin catch
rollback tran
set transaction isolation level READ COMMITTED
end catch
set transaction isolation level READ COMMITTED
END
The table "test" has many values, so "select * from teste" takes several seconds. I run the sp_LockReader at same time in two diferent query windows and the second one starts showing test table contents without the first one terminates.
Shouldn't serializeble level forces the second query to wait?
How do i get the described behaviour?
Thanks
SERIALIZABLE at the most basic means "hold locks for longer". When you SELECT, the held lock is a shared lock which allows other readers.
If you want to block readers, use WITH (TABLOCKX) hint to take an exclusive lock where you don't need SERIALIZABLE. Or XLOCK with SERIALIZABLE
In other words:
SERIALIZABLE = Isolation Level = lock duration, concurrency
XLOCK = mode= sharing/exclusivity
TABLOCK = Granularity = what is locked
TABLOCKX = combined
See this question/answer for more info
A serializable transaction whose output is not affected by other concurrent transactions. In your case, you are SELECTing twice from the table; neither of those transactions changes the result set of the other, so they may both run simultaneously.
Even if one transaction did update the table, this would not necessarily prevent the other from executing, as the database may work from snapshots.
Have a look here for a better explanation than I can provide... http://en.wikipedia.org/wiki/Isolation_%28database_systems%29
Another note here. If you're using XLOCK under a SERIALIZABLE isolation, other transactions with READ COMMITTED isolation will still be able to read XLOCK'ed rows.
To prevent that, use PAGLOCK along with XLOCK.
See here for details
http://support.microsoft.com/kb/324417