1. Trang chủ
  2. » Công Nghệ Thông Tin

Microsoft SQL Server 2008 R2 Unleashed- P146 ppsx

10 103 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 10
Dung lượng 206,55 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Optimistic Locking with Snapshot Isolation SQL Server 2008’s Snapshot Isolation mode provides another mechanism for implement-ing optimistic lockimplement-ing through its automatic row v

Trang 1

CHAPTER 37 Locking and Performance

equivalent to the Serializable Read isolation level The following hypothetical

example demonstrates the usage of the HOLDLOCKstatement within a transaction:

declare @seqno int

begin transaction

get a UNIQUE sequence number from sequence table

SELECT @seqno = isnull(seq#,0) + 1

from sequence WITH (HOLDLOCK)

in the absence of HOLDLOCK, shared lock will be released

and if some other concurrent transaction ran the same

command, both of them could get the same sequence number

UPDATE sequence

set seq# = @seqno

now go do something else with this unique sequence number

commit tran

NOTE

As discussed earlier in this chapter, in the “Deadlocks” section, using HOLDLOCKin this

manner leads to potential deadlocks between processes executing the transaction at

the same time For this reason, the HOLDLOCKhint, as well as the REPEATABLEREAD

andSERIALIZABLEhints, should be used sparingly, if at all In this example, it might be

better for the SELECTstatement to use an update or an exclusive lock on the

sequencetable, using the hints discussed later in this chapter, in the section “Lock

Type Hints.” Another option would be to use an application lock, as discussed

previous-ly in this chapter, in the section “Using Application Locks.”

NOLOCK—You can use this option to specify that no shared lock be placed on the

resource This option is similar to running a query at Isolation Level 0 (Read

Uncommitted), which allows the query to ignore exclusive locks and read

uncom-mitted changes The NOLOCKoption is a useful feature in reporting environments,

where the accuracy of the results is not critical

READUNCOMMITTED—This is the same as specifying the Read Uncommitted mode

when using the SET TRANSACTION ISOLATION LEVELcommand, and it is the same as

theNOLOCKtable hint

READCOMMITTED—This is the same as specifying the Read Committed mode when

you use the SET TRANSACTION ISOLATION LEVELcommand The query waits for

exclusive locks to be released before reading the data This is the default locking

isolation mode for SQL Server If the database option READ_COMMITTED_SNAPSHOTis

ON, SQL Server does not acquire shared locks on the data and uses row versioning

Trang 2

READCOMMITTEDLOCK—This option specifies that read operations acquire shared

locks as data is read and release those locks when the read operation is completed,

regardless of the setting of the READ_COMMITTED_SNAPSHOTdatabase option

REPEATABLEREAD—This is the same as specifying Repeatable Read mode with the

SET TRANSACTION ISOLATION LEVELcommand It prevents nonrepeatable reads

within a transaction and behaves similarly to the HOLDLOCKhint

SERIALIZABLE—This is the same as specifying Serializable Read mode with the SET

TRANSACTION ISOLATION LEVELcommand It prevents phantom reads within a

trans-action and behaves similarly to using the HOLDLOCKhint

READPAST—This hint specifies that the query skip over the rows or pages locked by

other transactions, returning only the data that can be read Read operations

specify-ingREADPASTare not blocked When specified in an UPDATEorDELETEstatement,

READPASTis applied only when reading data to identify which records to update

READPASTcan be specified only in transactions operating at the Read Committed or

Repeatable Read isolation levels This lock hint is useful when reading information

from a SQL Server table used as a work queue A query using READPASTskips past

queue entries locked by other transactions to the next available queue entry, without

having to wait for the other transactions to release their locks

Lock Granularity Hints

You can use to override lock granularity:

ROWLOCK—You can use this option to force the Lock Manager to place a row-level

lock on a resource instead of a page-level or a table-level lock You can use this

option in conjunction with the XLOCKlock type hint to force exclusive row locks

PAGLOCK—You can use this option to force a page-level lock on a resource instead of

a row-level or table-level lock You can use this option in conjunction with the XLOCK

lock type hint to force exclusive page locks

TABLOCK—You can use this option to force a table-level lock instead of a row-level

or page-level lock You can use this option in conjunction with the HOLDLOCKtable

hint to hold the table lock until the end of the transaction

TABLOCKX—You can use this option to force a table-level exclusive lock instead of a

row-level or page-level lock No shared or update locks are granted to other

transac-tions as long as this option is in effect If you are planning maintenance on a SQL

Server table and you don’t want interference from other transactions, using this

option is one of the ways to essentially put a table into a single-user mode

Lock Type Hints

You can use the following optimizer hints to override the lock type that SQL Server uses:

UPDLOCK—This option is similar to HOLDLOCKexcept that whereas HOLDLOCKuses a

shared lock on the resource, UPDLOCKplaces an update lock on the resource for the

Trang 3

CHAPTER 37 Locking and Performance

duration of the transaction This allows other processes to read the information, but

not acquire update or exclusive locks on the resource This option provides read

repeatability within the transaction while preventing deadlocks that can result when

usingHOLDLOCK

XLOCK—This option places an exclusive lock on the resource for the duration of the

transaction This prevents other processes from acquiring locks on the resource

Optimistic Locking

With many applications, clients need to fetch the data to browse through it, make

modifi-cations to one or more rows, and then post the changes back to the database in SQL

Server These human-speed operations are slow in comparison to machine-speed

opera-tions, and the time lag between the fetch and post might be significant (Consider a user

who goes to lunch after retrieving the data.)

For these applications, you would not want to use normal locking schemes such as

SERIALIZABLEorHOLDLOCKto lock the data so it can’t be changed from the time the user

retrieves it to the time he or she applies any updates This would violate one of the key

rules for minimizing locking contention and deadlocks that you should not allow user

interaction within transactions You would also lose all control over the duration of the

transaction In a multiuser OLTP environment, the indefinite holding of the shared locks

could significantly affect concurrency and overall application performance due to blocking

on locks and locking contention

On the other hand, if the locks are not held on the rows being read, another process could

update a row between the time it was initially read and when the update is posted When

the first process applies the update, it would overwrite the changes made by the other

process, resulting in a lost update

So how do you implement such an application? How do you allow users to retrieve

infor-mation without holding locks on the data and still ensure that lost updates do not occur?

Optimistic locking is a technique used in situations in which reading and modifying data

processes are widely separated in time Optimistic locking helps a client avoid overwriting

another client’s changes to a row without holding locks in the database

One approach for implementing optimistic locking is to use the rowversiondata type

Another approach is to take advantage of the optimistic concurrency features of snapshot

isolation

Optimistic Locking Using the rowversion Data Type

SQL Server 2008 provides a special data type called rowversionthat can be used for

opti-mistic locking purposes within applications The purpose of the rowversiondata type is to

serve as a version number in optimistic locking schemes SQL Server automatically

gener-ates the value for a rowversioncolumn whenever a row that contains a column of this

type is inserted or updated The rowversiondata type is an 8-byte binary data type, and

Trang 4

other than guaranteeing that the value is unique and monotonically increasing, the value

is not meaningful; you cannot look at the individual bytes and make any sense of them

NOTE

In previous versions of SQL Server, the rowversiondata type was also referred to as

thetimestampdata type While this data type synonym still exists in SQL Server 2008,

it has been deprecated and the rowversiondata type name should be used instead to

ensure future compatibility

In an application that uses optimistic locking, the client reads one or more records from

the table, being sure to retrieve the primary key and current value of therowversion

column for each row, along with any other desired data columns Because the query is not

run within a transaction, any locks acquired for theSELECTare released after the data has

been read At some later time, when the client wants to update a row, it must ensure that

no other client has changed the same row in the intervening time TheUPDATEstatement

must include aWHEREclause that compares therowversionvalue retrieved with the

origi-nal query, with the currentrowversionvalue for the record in the database If the

rowversionvalues match—that is, if the value that was read is the same as the value

currently in the database—no changes to that row have occurred since it was originally

retrieved Therefore, the change attempted by the application can proceed If the

rowversionvalue in the client application does not match the value in the database, that

particular row has been changed since the original retrieval of the record As a result, the

state of the row that the application is attempting to modify is not the same as the row

that currently exists in the database As a result, the transaction should not be allowed to

take place, to avoid the lost update problem

To ensure that the client application does not overwrite the changes made by another

process, the client needs to prepare the T-SQLUPDATEstatement in a special way, using

therowversioncolumn as a versioning marker The following pseudocode represents the

general structure of such an update:

UPDATE theTable

SET theChangedColumns = theirNewValues

WHERE primaryKeyColumns = theirOldValues

AND rowversion = itsOldValue

Because theWHEREclause includes the primary key, theUPDATEcan apply only to exactly

one row or to no rows; it cannot apply to more than one row because the primary key is

unique The second part of theWHEREclause provides the optimistic “locking.” If another

client has updated the row, therowversionno longer has its old value (remember that the

server changes therowversionvalue automatically with each update), and theWHEREclause

does not match any rows The client needs to check whether any rows were updated If the

number of rows affected by the update statement is zero, the row has been modified since

Trang 5

CHAPTER 37 Locking and Performance

it was originally retrieved The application can then choose to reread the data or do

what-ever recovery it deems appropriate This approach has one problem: how does the

applica-tion know whether it didn’t match the row because therowversionwas changed, because

the primary key had changed, or because the row had been deleted altogether?

In SQL Server 2000, there was an undocumented tsequal()function (which was

docu-mented in prior releases) that could be used in a WHEREclause to compare the rowversion

value retrieved by the client application with the rowversionvalue in the database If the

rowversionvalues matched, the update would proceed If not, the update would fail, with

error message 532, to indicate that the row had been modified Unfortunately, this

func-tion is no longer provided in SQL Server 2005 and later releases Any attempt to use it

now results in a syntax error As an alternative, you can programmatically check whether

the update modified any rows, and if not, you can check whether the row still exists and

return the appropriate message Listing 37.7 provides an example of a stored procedure

that implements this strategy

LISTING 37.7 An Example of a Procedure for Optimistic Locking

create proc optimistic_update

@id int, provide the primary key for the record

@data_field_1 varchar(10), provide the data value to be updated

@rowversion rowversion pass in the rowversion value retrieved with

the initial data retrieval as

Attempt to modify the record

update data_table

set data_field_1 = @data_field_1

where id = @id

and versioncol = @rowversion

Check to see if no rows updated

IF @@ROWCOUNT=0

BEGIN

if exists (SELECT * FROM data_table WHERE id=@id)

The row exists but the rowversions don’t match

begin

raiserror (‘The row with id “%d” has been updated since it was read’,

10, 1, @id) return -101

end

else the row has been deleted

begin

raiserror (‘The row with id “%d” has been deleted since it was read’,

10, 2, @id) return -102

end

end

Trang 6

ELSE

PRINT ‘Data Updated’

return 0

Using this approach, if the update doesn’t modify any rows, the application receives an

error message and knows for sure that the reason the update didn’t take place is that

either the rowversionvalue didn’t match or the row was deleted If the row is found and

therowversionvalues match, the update proceeds normally

Optimistic Locking with Snapshot Isolation

SQL Server 2008’s Snapshot Isolation mode provides another mechanism for

implement-ing optimistic lockimplement-ing through its automatic row versionimplement-ing If a process reads data within

a transaction when Snapshot Isolation mode is enabled, no locks are acquired or held on

the current version of the data row The process reads the version of the data at the time

of the query Because no locks are held, it doesn’t lead to blocking, and another process

can modify the data after it has been read If another process does modify a data row read

by the first process, a new version of the row is generated If the original process then

attempts to update that data row, SQL Server automatically prevents the lost update

problem by checking the row version In this case, because the row version is different,

SQL Server prevents the original process from modifying the data row When it attempts

to modify the data row, the following error message appears:

Msg 3960, Level 16, State 4, Line 2

Snapshot isolation transaction aborted due to update conflict You cannot use

snapshot isolation to access table ‘dbo.data_table’ directly or indirectly in

database ‘bigpubs2008’ to update, delete, or insert the row that has been modified

or deleted by another transaction Retry the transaction or change the isolation

level for the update/delete statement

To see how this works, you can create the following table:

use bigpubs2008

go

The first statement is used to disable any previously created

DDL triggers in the database which would prevent creating a new table

DISABLE TRIGGER ALL ON DATABASE

go

create table data_table

(id int identity,

data_field_1 varchar(10),

timestamp timestamp)

go

insert data_table (data_field_1) values (‘foo’)

go

Next, you need to ensure that bigpubs2008is configured to allow snapshot isolation:

Trang 7

CHAPTER 37 Locking and Performance

ALTER DATABASE bigpubs2008 SET ALLOW_SNAPSHOT_ISOLATION ON

In one user session, you execute the following SQL statements:

SET TRANSACTION ISOLATION LEVEL SNAPSHOT

go

begin tran

select * from data_table

go

id data_field_1 timestamp

- -

-1 foo 0x0000000000000BC4

Now, in another user session, you execute the following UPDATEstatement:

update data_table set data_field_1 = ‘bar’

where id = 1

Then you go back to the original session and attempt the following update:

update data_table set data_field_1 = ‘fubar’

where id = 1

go

Msg 3960, Level 16, State 4, Line 2

Snapshot isolation transaction aborted due to update conflict You cannot use

snapshot isolation to access table ‘dbo.data_table’ directly or indirectly in

database ‘bigpubs2008’ to update, delete, or insert the row that has been modified

or deleted by another transaction Retry the transaction or change the isolation

level for the update/delete statement

Note that for the first process to hold on to the row version, the SELECTandUPDATE

state-ments must be run in the same transaction When the transaction is committed or rolled

back, the row version acquired by the SELECTstatement is released However, because the

SELECTstatement run at the Snapshot Isolation level does not hold any locks, there are no

locks being acquired or held by that SELECTstatement within the transaction, so it avoids

the problems that would normally be encountered by using HOLDLOCKor the Serializable

Read isolation level Because no locks were held on the data row, the other process was

allowed to update the row after it was retrieved, generating a new version of the row The

automatic row versioning provided by SQL Server’s Snapshot Isolation mode prevented

the first process from overwriting the update performed by the second process, thereby

preventing a lost update

Trang 8

CAUTION

Locking contention is prevented in the preceding example only because the transaction

performed only a SELECTbefore attempting the UPDATE A SELECTrun with Snapshot

Isolation mode enabled reads the current version of the row and does not acquire or

hold locks on the actual data row However, if the process were to perform any other

modification on the data row, the update or exclusive locks acquired would be held

until the end of the transaction, which could lead to locking contention, especially if

user interaction is allowed within the transaction after the update or exclusive locks are

acquired

Also, be aware of the overhead generated in tempdbwhen Snapshot Isolation mode is

enabled for a database, as described in the section “Transaction Isolation Levels in

SQL Server,” earlier in this chapter

Because of the overhead incurred by snapshot isolation and the cost of having to roll

back update conflicts, you should consider using Snapshot Isolation mode only to

pro-vide optimistic locking for systems where there is little concurrent updating of the

same resource so that it is unlikely that your transactions have to be rolled back

because of an update conflict

Summary

Locking is critical in a multiuser environment for providing transaction isolation SQL

Server supports all ANSI-defined transaction isolation levels, including the Snapshot

Isolation level for applications that can benefit from optimistic concurrency The Lock

Manager in SQL Server automatically locks data at the row level or higher, as necessary, to

provide the appropriate isolation while balancing the locking overhead with concurrent

access to the data It is important to understand how locking works and what its effect is

on application performance to develop efficient queries and applications

SQL Server provides a number of tools for monitoring and identifying locking problems

and behavior In addition, SQL Server provides a number of table-locking hints that give the

developer better control over the default lock types and granularity used for certain queries

Although following the guidelines to minimize locking contention in applications is

important, another factor that affects locking behavior and query performance is the

actual database design Chapter 38, “Database Design and Performance,” discusses

data-base design and its effect on datadata-base performance and provides guidelines to help ensure

that transactions and T-SQL code run efficiently

Trang 9

This page intentionally left blank

Trang 10

Database Design and

Performance

What’s New in Database Design and Performance

Basic Tenets of Designing for Performance

Logical Database Design Issues

Denormalizing a Database

Database Filegroups and Performance

RAID Technology

SQL Server and SAN Technology

Various factors contribute to the optimal performance of

a database application Some of these factors include logical

database design (rules of normalization), physical database

design (denormalization, indexes, data placement), choice

of hardware (SMP servers/multiprocessor servers), network

bandwidth (LAN versus WAN), client and server

configura-tion (memory, CPU), data access techniques (ODBC, ADO,

OLEDB), and application architecture (two-tier versus

n-tier) This chapter helps you understand some of the key

database design issues to ensure that you have a reliable

high-performance application

NOTE

Index design is often considered part of physical

data-base design Because index design guidelines and the

impact of indexes on query and update performance

are covered in detail in Chapter 34, “Data Structures,

Indexes and Performance,” this chapter does not

dis-cuss index design It focuses instead on other aspects

of database design and performance

What’s New in Database Design

and Performance

Many of the database design and performance

considera-tions that applied to previous versions of SQL Server still

apply to SQL Server 2008 These principles are basic in

Ngày đăng: 05/07/2014, 02:20

TỪ KHÓA LIÊN QUAN