dbTalk Databases Forums  

Transaction Isolation Level

comp.databases.ms-sqlserver comp.databases.ms-sqlserver


Discuss Transaction Isolation Level in the comp.databases.ms-sqlserver forum.



Reply
 
Thread Tools Display Modes
  #1  
Old   
dhek
 
Posts: n/a

Default Transaction Isolation Level - 11-03-2007 , 04:24 AM






Hi,

I have 1 SQL statement selecting data from various tables and updating other
tables.

The question then is how do I prevent other applications from modifying the
tables that I'm working on (that is while my transaction is being executed)?


I know that the isolation level should be either REPEATABLE READ or
SERIALIZABLE. But I need confirmation on if one of these actually solve my
issue - prevents other applications/threads from modifying/inserting data
into the same tables that I'm working on.



Thanks in advance,
Daniel



Reply With Quote
  #2  
Old   
Erland Sommarskog
 
Posts: n/a

Default Re: Transaction Isolation Level - 11-03-2007 , 04:47 AM






dhek (dhek (AT) dhek (DOT) dk) writes:
Quote:
I have 1 SQL statement selecting data from various tables and updating
other tables.

The question then is how do I prevent other applications from modifying
the tables that I'm working on (that is while my transaction is being
executed)?


I know that the isolation level should be either REPEATABLE READ or
SERIALIZABLE. But I need confirmation on if one of these actually solve my
issue - prevents other applications/threads from modifying/inserting data
into the same tables that I'm working on.
It's difficult to give a single answer, since I don't know your exact
requirements, so I have to answer in genric terms.

If you want a consistent snapshot of how the data looks in this precise
moment, the isolation level you should use is snapshot isolation. Snapshot
isolation is available only in SQL 2005 and later. Furthermore the database
must be configured to permit snapshot isolation. When you have snapshot is
created when the transaction starts, or at latest when you start to read
data. If data is updated while your query runs, you will not see these
updates. This gives you a consistent view - but it may also give you
outdated data, depending on how you look at it.

On SQL 2000, snapshot isolation is not available, and the only foolproof
way to get consistent data, is to set the database in single-user mode.

In the default isolation level, READ COMMITTED, if you read the same
row twice, you may get different results in different accesses. For
instance, if you run:

SELECT O.OrderID, E.EmployeeID, E.LastName
FROM Orders O
JOIN Employees E ON O.EmployeeID = E.EmployeeID

You may see different last names for the same employee ID if the query
plan uses a loop join, and the last name is updated while the query is
running.

In the next level, REPEATABLE READ locks are held, and you are guaranteed
that reading the same row twice will yield the same result. However, if
the last name of employee 8 was Grønkjær when the query started, and
updated to Gravesen before you have read any orders with employee 8,
you would see Gravesen in the result set.

SERIALIZABLE adds protection against "phantom insert", so if you read the
same range twice, you will get the same result. That is, if you run
SELECT MAX(OrderID) FROM Orders twice in the same serializable transaction,
you will get the same result. But if a order is added after you started the
transaction, but before your query runs, the order will show up.


--
Erland Sommarskog, SQL Server MVP, esquel (AT) sommarskog (DOT) se

Books Online for SQL Server 2005 at
http://www.microsoft.com/technet/pro...ads/books.mspx
Books Online for SQL Server 2000 at
http://www.microsoft.com/sql/prodinf...ons/books.mspx


Reply With Quote
  #3  
Old   
dhek
 
Posts: n/a

Default Re: Transaction Isolation Level - 11-03-2007 , 05:32 AM



Well, my issue is that I'm reading data from tables A, B, C and D and
updates table E.

What I need to prevent is 2 things:

1) New rows must not be added to either table A and B while my transaction
is executing
2) Existing rows must not be modified

My query is executed on a SQL server 2005. I do not have the option to
change the configuration of it.

Am I supposed to use table locks in my query

SELECT A.c1, B.c1, C.c1, D.d1
FROM ...
WHERE ...
WITH (TABLOCK, UPDLOCK, HOLDLOCK)

UPDATE E.1
SET ...
WHERE ...



"Erland Sommarskog" <esquel (AT) sommarskog (DOT) se> wrote

Quote:
dhek (dhek (AT) dhek (DOT) dk) writes:
I have 1 SQL statement selecting data from various tables and updating
other tables.

The question then is how do I prevent other applications from modifying
the tables that I'm working on (that is while my transaction is being
executed)?


I know that the isolation level should be either REPEATABLE READ or
SERIALIZABLE. But I need confirmation on if one of these actually solve
my
issue - prevents other applications/threads from modifying/inserting data
into the same tables that I'm working on.

It's difficult to give a single answer, since I don't know your exact
requirements, so I have to answer in genric terms.

If you want a consistent snapshot of how the data looks in this precise
moment, the isolation level you should use is snapshot isolation. Snapshot
isolation is available only in SQL 2005 and later. Furthermore the
database
must be configured to permit snapshot isolation. When you have snapshot is
created when the transaction starts, or at latest when you start to read
data. If data is updated while your query runs, you will not see these
updates. This gives you a consistent view - but it may also give you
outdated data, depending on how you look at it.

On SQL 2000, snapshot isolation is not available, and the only foolproof
way to get consistent data, is to set the database in single-user mode.

In the default isolation level, READ COMMITTED, if you read the same
row twice, you may get different results in different accesses. For
instance, if you run:

SELECT O.OrderID, E.EmployeeID, E.LastName
FROM Orders O
JOIN Employees E ON O.EmployeeID = E.EmployeeID

You may see different last names for the same employee ID if the query
plan uses a loop join, and the last name is updated while the query is
running.

In the next level, REPEATABLE READ locks are held, and you are guaranteed
that reading the same row twice will yield the same result. However, if
the last name of employee 8 was Grønkjær when the query started, and
updated to Gravesen before you have read any orders with employee 8,
you would see Gravesen in the result set.

SERIALIZABLE adds protection against "phantom insert", so if you read the
same range twice, you will get the same result. That is, if you run
SELECT MAX(OrderID) FROM Orders twice in the same serializable
transaction,
you will get the same result. But if a order is added after you started
the
transaction, but before your query runs, the order will show up.


--
Erland Sommarskog, SQL Server MVP, esquel (AT) sommarskog (DOT) se

Books Online for SQL Server 2005 at
http://www.microsoft.com/technet/pro...ads/books.mspx
Books Online for SQL Server 2000 at
http://www.microsoft.com/sql/prodinf...ons/books.mspx



Reply With Quote
  #4  
Old   
Erland Sommarskog
 
Posts: n/a

Default Re: Transaction Isolation Level - 11-03-2007 , 04:13 PM



dhek (dhek (AT) dhek (DOT) dk) writes:
Quote:
Well, my issue is that I'm reading data from tables A, B, C and D and
updates table E.

What I need to prevent is 2 things:

1) New rows must not be added to either table A and B while my transaction
is executing
2) Existing rows must not be modified
I'm not sure that I get this. Assuming you assemble data into a temp
table or a table variable, and you batch goes:

INSERT #tmp(...)
SELECT ....
FROM A, B
...

INSERT #tmp(...)
SELECT ...
FROM C, D

UPDATE E
SET ...
FROM E
JOIN #tmp...

Why would it be an issue if some adds or modifies rows into A or B
once you have run that SELECT statement? I can possibly understand
that you don't want permit rows to be added or modified in C or D while
you are reading A and B. But once you have read A or B, it cannot matter
if modifications happens while your transaction is running, or if they
are held up until your transaction completes.

Quote:
My query is executed on a SQL server 2005. I do not have the option to
change the configuration of it.
Well, if you want to read that is consistent at a certain moment in
time, snapshot isolation is your only foolproof option. It also has the
advantage of not blocking updates.





--
Erland Sommarskog, SQL Server MVP, esquel (AT) sommarskog (DOT) se

Books Online for SQL Server 2005 at
http://www.microsoft.com/technet/pro...ads/books.mspx
Books Online for SQL Server 2000 at
http://www.microsoft.com/sql/prodinf...ons/books.mspx


Reply With Quote
  #5  
Old   
Greg D. Moore \(Strider\)
 
Posts: n/a

Default Re: Transaction Isolation Level - 11-03-2007 , 08:02 PM





"dhek" <dhek (AT) dhek (DOT) dk> wrote

Quote:
Well, my issue is that I'm reading data from tables A, B, C and D and
updates table E.

What I need to prevent is 2 things:

1) New rows must not be added to either table A and B while my transaction
is executing
2) Existing rows must not be modified
Why?

If that is truly the case, then yes, you need a table lock.

But this seems like a fairly unusual requirement. Sure your design is
really what you want?


Quote:
My query is executed on a SQL server 2005. I do not have the option to
change the configuration of it.

Am I supposed to use table locks in my query

SELECT A.c1, B.c1, C.c1, D.d1
FROM ...
WHERE ...
WITH (TABLOCK, UPDLOCK, HOLDLOCK)

UPDATE E.1
SET ...
WHERE ...



"Erland Sommarskog" <esquel (AT) sommarskog (DOT) se> wrote in message
news:Xns99DD791FBE224Yazorman (AT) 127 (DOT) 0.0.1...
dhek (dhek (AT) dhek (DOT) dk) writes:
I have 1 SQL statement selecting data from various tables and updating
other tables.

The question then is how do I prevent other applications from modifying
the tables that I'm working on (that is while my transaction is being
executed)?


I know that the isolation level should be either REPEATABLE READ or
SERIALIZABLE. But I need confirmation on if one of these actually solve
my
issue - prevents other applications/threads from modifying/inserting
data
into the same tables that I'm working on.

It's difficult to give a single answer, since I don't know your exact
requirements, so I have to answer in genric terms.

If you want a consistent snapshot of how the data looks in this precise
moment, the isolation level you should use is snapshot isolation.
Snapshot
isolation is available only in SQL 2005 and later. Furthermore the
database
must be configured to permit snapshot isolation. When you have snapshot
is
created when the transaction starts, or at latest when you start to read
data. If data is updated while your query runs, you will not see these
updates. This gives you a consistent view - but it may also give you
outdated data, depending on how you look at it.

On SQL 2000, snapshot isolation is not available, and the only foolproof
way to get consistent data, is to set the database in single-user mode.

In the default isolation level, READ COMMITTED, if you read the same
row twice, you may get different results in different accesses. For
instance, if you run:

SELECT O.OrderID, E.EmployeeID, E.LastName
FROM Orders O
JOIN Employees E ON O.EmployeeID = E.EmployeeID

You may see different last names for the same employee ID if the query
plan uses a loop join, and the last name is updated while the query is
running.

In the next level, REPEATABLE READ locks are held, and you are guaranteed
that reading the same row twice will yield the same result. However, if
the last name of employee 8 was Grønkjær when the query started, and
updated to Gravesen before you have read any orders with employee 8,
you would see Gravesen in the result set.

SERIALIZABLE adds protection against "phantom insert", so if you read the
same range twice, you will get the same result. That is, if you run
SELECT MAX(OrderID) FROM Orders twice in the same serializable
transaction,
you will get the same result. But if a order is added after you started
the
transaction, but before your query runs, the order will show up.


--
Erland Sommarskog, SQL Server MVP, esquel (AT) sommarskog (DOT) se

Books Online for SQL Server 2005 at
http://www.microsoft.com/technet/pro...ads/books.mspx
Books Online for SQL Server 2000 at
http://www.microsoft.com/sql/prodinf...ons/books.mspx


--
Greg Moore
SQL Server DBA Consulting Remote and Onsite available!
Email: sql (at) greenms.com http://www.greenms.com/sqlserver.html




Reply With Quote
  #6  
Old   
dhek
 
Posts: n/a

Default Re: Transaction Isolation Level - 11-04-2007 , 03:04 AM



ok, let me try to be more clear.

The thing is I have a database containing various types of information - for
instance orders.
Instead of letting each record in an order contain a timestamp indicating
the datatime the record was replicated to another system, I have a table
containing replication times for various types of objects.

This means that while I initiate a transaction selecting all new orders it
is possible for others to add other new orders to the database which I will
never be aware of.
- in my transaction after having gotten new orders I set a timestamp
indicating the datetime of my last replication. If someone has added new
records meanwhile I executed my select statement and performed the update
statement, then these new records will never be replicated because their
timestamp will be less than than the one I set in my update-statement when
finished.

Hope this clearfies my issue.



"dhek" <dhek (AT) dhek (DOT) dk> wrote

Quote:
Well, my issue is that I'm reading data from tables A, B, C and D and
updates table E.

What I need to prevent is 2 things:

1) New rows must not be added to either table A and B while my transaction
is executing
2) Existing rows must not be modified

My query is executed on a SQL server 2005. I do not have the option to
change the configuration of it.

Am I supposed to use table locks in my query

SELECT A.c1, B.c1, C.c1, D.d1
FROM ...
WHERE ...
WITH (TABLOCK, UPDLOCK, HOLDLOCK)

UPDATE E.1
SET ...
WHERE ...



"Erland Sommarskog" <esquel (AT) sommarskog (DOT) se> wrote in message
news:Xns99DD791FBE224Yazorman (AT) 127 (DOT) 0.0.1...
dhek (dhek (AT) dhek (DOT) dk) writes:
I have 1 SQL statement selecting data from various tables and updating
other tables.

The question then is how do I prevent other applications from modifying
the tables that I'm working on (that is while my transaction is being
executed)?


I know that the isolation level should be either REPEATABLE READ or
SERIALIZABLE. But I need confirmation on if one of these actually solve
my
issue - prevents other applications/threads from modifying/inserting
data
into the same tables that I'm working on.

It's difficult to give a single answer, since I don't know your exact
requirements, so I have to answer in genric terms.

If you want a consistent snapshot of how the data looks in this precise
moment, the isolation level you should use is snapshot isolation.
Snapshot
isolation is available only in SQL 2005 and later. Furthermore the
database
must be configured to permit snapshot isolation. When you have snapshot
is
created when the transaction starts, or at latest when you start to read
data. If data is updated while your query runs, you will not see these
updates. This gives you a consistent view - but it may also give you
outdated data, depending on how you look at it.

On SQL 2000, snapshot isolation is not available, and the only foolproof
way to get consistent data, is to set the database in single-user mode.

In the default isolation level, READ COMMITTED, if you read the same
row twice, you may get different results in different accesses. For
instance, if you run:

SELECT O.OrderID, E.EmployeeID, E.LastName
FROM Orders O
JOIN Employees E ON O.EmployeeID = E.EmployeeID

You may see different last names for the same employee ID if the query
plan uses a loop join, and the last name is updated while the query is
running.

In the next level, REPEATABLE READ locks are held, and you are guaranteed
that reading the same row twice will yield the same result. However, if
the last name of employee 8 was Grønkjær when the query started, and
updated to Gravesen before you have read any orders with employee 8,
you would see Gravesen in the result set.

SERIALIZABLE adds protection against "phantom insert", so if you read the
same range twice, you will get the same result. That is, if you run
SELECT MAX(OrderID) FROM Orders twice in the same serializable
transaction,
you will get the same result. But if a order is added after you started
the
transaction, but before your query runs, the order will show up.


--
Erland Sommarskog, SQL Server MVP, esquel (AT) sommarskog (DOT) se

Books Online for SQL Server 2005 at
http://www.microsoft.com/technet/pro...ads/books.mspx
Books Online for SQL Server 2000 at
http://www.microsoft.com/sql/prodinf...ons/books.mspx





Reply With Quote
  #7  
Old   
dhek
 
Posts: n/a

Default Re: Transaction Isolation Level - 11-04-2007 , 03:17 AM




"Erland Sommarskog" <esquel (AT) sommarskog (DOT) se> wrote

Quote:
dhek (dhek (AT) dhek (DOT) dk) writes:
Well, my issue is that I'm reading data from tables A, B, C and D and
updates table E.

What I need to prevent is 2 things:

1) New rows must not be added to either table A and B while my
transaction
is executing
2) Existing rows must not be modified

I'm not sure that I get this. Assuming you assemble data into a temp
table or a table variable, and you batch goes:

INSERT #tmp(...)
SELECT ....
FROM A, B
...

INSERT #tmp(...)
SELECT ...
FROM C, D

UPDATE E
SET ...
FROM E
JOIN #tmp...
As mentioned I perform a SELECT statement followed by an UPDATE-statement in
my transaction.

When I get new Orders and related information from various tables I need to
update a synchronization-table indicating the time of last sync.
My problem is that with this setup I need to prevent others from adding new
orders to the table while my transaction is executing to prevent "lost
records".

Quote:
Why would it be an issue if some adds or modifies rows into A or B
once you have run that SELECT statement? I can possibly understand
that you don't want permit rows to be added or modified in C or D while
you are reading A and B. But once you have read A or B, it cannot matter
if modifications happens while your transaction is running, or if they
are held up until your transaction completes.
With the setup u proposed in your example I agree - it would be foolish not
to allow others to read/write data to table A,B when done with those
table:-)
If my sync-indicator had only been located in the records that are selected
I would not have a problem at all - only need to set the transaction level
to READ COMMITED or SYNCHRONIZED. I do not have the option of setting it to
snapshot isolation (not supported by my application.)


Quote:
My query is executed on a SQL server 2005. I do not have the option to
change the configuration of it.

Well, if you want to read that is consistent at a certain moment in
time, snapshot isolation is your only foolproof option. It also has the
advantage of not blocking updates.
Do u mean is allows for records to be modified or is it table u refer to?




Reply With Quote
  #8  
Old   
dhek
 
Posts: n/a

Default Re: Transaction Isolation Level - 11-04-2007 , 03:20 AM



Quote:
Well, my issue is that I'm reading data from tables A, B, C and D and
updates table E.

What I need to prevent is 2 things:

1) New rows must not be added to either table A and B while my
transaction is executing
2) Existing rows must not be modified

Why?

If that is truly the case, then yes, you need a table lock.

But this seems like a fairly unusual requirement. Sure your design is
really what you want?
With the current setup in the database I fear this is what I want (though
I'm not very keen on the idea either:-o). I'm just trying to investigate my
options for disallowing tables changes while my transaction is executing to
prevent "lost records" as mentioned in one of my other replies.




Reply With Quote
  #9  
Old   
dhek
 
Posts: n/a

Default Re: Transaction Isolation Level - 11-04-2007 , 03:30 AM



Quote:
With the setup u proposed in your example I agree - it would be foolish
not to allow others to read/write data to table A,B when done with those
table:-)
If my sync-indicator had only been located in the records that are
selected I would not have a problem at all - only need to set the
transaction level to READ COMMITED or SYNCHRONIZED. I do not have the
option of setting it to snapshot isolation (not supported by my
application.)
Sorry, I of course ment REPEATABLE READ and not READ COMMITED.




Reply With Quote
  #10  
Old   
dhek
 
Posts: n/a

Default Re: Transaction Isolation Level - 11-04-2007 , 06:27 AM



Quote:
I know that the isolation level should be either REPEATABLE READ or
SERIALIZABLE. But I need confirmation on if one of these actually solve my
issue - prevents other applications/threads from modifying/inserting data
into the same tables that I'm working on.

When reading about SERIALIZABLE in
http://en.wikipedia.org/wiki/Isolati...mputer_science) I get the
understanding that the objects involved in a SELECT-statement (that is all
coloumns involved i vaious tables) will be locked. In essence this would
render it impossible to insert new records into the tables used in my
SELECT-statement which I believe is exaclty what I need.

Is this understanding correct?




Reply With Quote
Reply




Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Powered by vBulletin Version 3.5.3
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.