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

Tài liệu Setting the Transaction Isolation Level pdf

10 494 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

Tiêu đề Setting the transaction isolation level
Trường học Standard University
Chuyên ngành Database Management
Thể loại Tài liệu
Năm xuất bản 2023
Thành phố Hanoi
Định dạng
Số trang 10
Dung lượng 41,51 KB

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

Nội dung

Table 14.3: SQL Standard Isolation Levels ISOLATION LEVEL DESCRIPTION READ UNCOMMITTED Phantoms, nonrepeatable reads, and dirty reads are permitted.. Table 14.3: SQL Standard Isolatio

Trang 1

Setting the Transaction Isolation Level

The transaction isolation level is the degree to which the changes made by one

transaction are separated from other concurrent transactions Before I get into the details

of the various transaction isolation levels, you need to understand the types of problems that might occur when current transactions attempt to access the same rows in a table In the following list, I'll use examples of two concurrent transactions that are accessing the same rows to illustrate the three types of potential transaction processing problems:

Phantoms Transaction 1 reads a set of rows returned by a specified WHERE

clause Transaction 2 then inserts a new row, which also happens to satisfy the WHERE clause of the query previously used byTransaction 1 Transaction 1 then reads the rows again using the same query but now sees the additional row just inserted by Transaction 2 This new row is known as a "phantom," because to Transaction 1, this row seems to have magically appeared

Nonrepeatable reads Transaction 1 reads a row, and Transaction 2 updates the same row just read by Transaction 1 Transaction 1 then reads the same row again and discovers that the row it read earlier is now different This is known as a

"nonrepeatable read," because the row originally read by Transaction 1 has been changed

Dirty reads Transaction 1 updates a row but doesn't commit the update

Transaction 2 reads the updated row Transaction 1 then performs a rollback, undoing the previous update Now the row just read by Transaction 2 is no longer valid (or it's "dirty") because the update made by Transaction 1 wasn't committed when the row was read by Transaction 2

To deal with these potential problems, databases implement various levels of transaction isolation to prevent concurrent transactions from interfering with each other The SQL standard defines four isolation levels, which are shown in Table 14.3 These levels are shown in order of increasing isolation

Table 14.3: SQL Standard Isolation Levels

ISOLATION

LEVEL

DESCRIPTION

READ

UNCOMMITTED

Phantoms, nonrepeatable reads, and dirty reads are permitted

READ COMMITTED Phantoms and nonrepeatable reads are permitted, but dirty reads

are not This is the default for SQL Server

REPEATABLE

READ

Phantoms are permitted, but nonrepeatable and dirty reads are not

Trang 2

Table 14.3: SQL Standard Isolation Levels

ISOLATION

LEVEL

DESCRIPTION

SERIALIZABLE Phantoms, nonrepeatable reads, and dirty reads are not permitted

This is the default for the SQL standard

SQL Server supports all of these transaction isolation levels The default transaction isolation level defined by the SQL standard is SERIALIZABLE, but the default used by SQL Server is READ COMMITTED, which is acceptable for most applications

Warning When you set the transaction isolation level to SERIALIZABLE, any rows you

access within a subsequent transaction will be "locked," meaning that no other

transaction can modify those rows Even rows you retrieve using a SELECT

statement will be locked You must commit or roll back the transaction to release the locks and allow other transactions to access the same rows Use

SERIALIZABLE only when you must ensure that your transaction is isolated

from other transactions You'll learn more about this later in the section

"Understanding SQL Server Locks."

In addition, ADO.NET supports a number of transaction isolation levels, which are defined in the System.Data.IsolationLevel enumeration Table 14.4 shows the members

of this enumeration

Table 14.4: IsolationLevel Enumeration Members

ISOLATION

LEVEL

DESCRIPTION

Chaos Pending changes from more isolated transactions cannot be

overwritten SQL Server doesn't support this isolation level

ReadCommitted Phantoms and nonrepeatable reads are permitted, but dirty reads are

not This is the default

ReadUncommitted Phantoms, nonrepeatable reads, and dirty reads are permitted RepeatableRead Phantoms are permitted, but nonrepeatable and dirty reads are not Serializable Phantoms, nonrepeatable reads, and dirty reads are not permitted Unspecified A different isolation level than the one specified is being used, but

the level cannot be determined SQL Server doesn't support this isolation level

In the next two sections, you'll learn how to set the transaction isolation level using T-SQL and a SqlTransaction object

Trang 3

Setting the Transaction Isolation Level Using T-SQL

As well as learning to set the transaction isolation level using T-SQL, you'll see an example that shows the effect of setting different transaction isolation levels in SQL Server using the Query Analyzer tool

To set the transaction isolation level in T-SQL, you use the SET TRANSACTION ISOLATION LEVEL command The syntax for this command is as follows:

SET TRANSACTION ISOLATION LEVEL {

READ COMMITTED |

READ UNCOMMITTED |

REPEATABLE READ |

SERIALIZABLE

}

As you can see from the previous syntax, you can set the transaction isolation to any of the levels shown earlier in Table 14.3

The following example sets the transaction isolation level to SERIALIZABLE:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE

Note The transaction isolation level is set for your session Therefore, if you perform multiple transactions in a session, all your transactions will use the same level If

you want to change the level in your session, you simply execute another SET TRANSACTION ISOLATION LEVEL command with your new level All

subsequent transactions in your session will use the new level

The following example sets the transaction isolation level to READ COMMITTED: SET TRANSACTION ISOLATION LEVEL READ COMMITTED

Let's look at a complete example that sets the transaction isolation level using T-SQL

Listing 14.3 shows an example T-SQL script that sets the transaction isolation level first

to SERIALIZABLE and executes a transaction, and then sets the level to READ

COMMITTED and executes another transaction

Listing 14.3: TransactionIsolation.sql

/*

TransactionIsolation.sql illustrates how to set the

transaction isolation level

Trang 4

*/

USE Northwind

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE

BEGIN TRANSACTION

SELECT CustomerID, CompanyName

FROM Customers

WHERE CustomerID IN ('ALFKI', 'J8COM')

INSERT INTO Customers (

CustomerID, CompanyName

) VALUES (

'J8COM', 'J8 Company'

)

UPDATE Customers

SET CompanyName = 'Widgets Inc.'

WHERE CustomerID = 'ALFKI'

SELECT CustomerID, CompanyName

FROM Customers

WHERE CustomerID IN ('ALFKI', 'J8COM')

COMMIT TRANSACTION

SET TRANSACTION ISOLATION LEVEL READ COMMITTED BEGIN TRANSACTION

UPDATE Customers

SET CompanyName = 'Alfreds Futterkiste'

WHERE CustomerID = 'ALFKI'

DELETE FROM Customers

WHERE CustomerID = 'J8COM'

SELECT CustomerID, CompanyName

FROM Customers

WHERE CustomerID IN ('ALFKI', 'J8COM')

COMMIT TRANSACTION

Trang 5

Figure 14.2 shows the TransactionIsolation.sql script being run in Query Analyzer In the results pane in the lower half of Query Analyzer, the first two sets of rows are generated

by the first transaction, and the final single row is generated by the second transaction

Figure 14.2: Running the TransactionIsolation.sql script in Query Analyzer

Setting the Transaction Isolation Level of a SqlTransaction Object

Along with setting the transaction isolation level of a SqlTransaction object, you'll see an example that shows the effect of setting different levels in a C# program

You create a SqlTransaction object by calling the BeginTransaction() method of the SqlConnection object This method is overloaded as follows:

SqlTransaction BeginTransaction()

SqlTransaction BeginTransaction(IsolationLevel myIsolationLevel)

SqlTransaction BeginTransaction(string transactionName)

SqlTransaction BeginTransaction(IsolationLevel myIsolationLevel, string

transactionName)

where

constant from the System.Data.IsolationLevel enumeration, for which members were shown earlier in Table 14.4

your transaction

In the examples in this section, assume you have an open SqlConnection named

mySqlConnection that is connected to the SQL Server Northwind database The

Trang 6

following example creates a SqlTransaction named serializableTrans by calling the

BeginTransaction() method of mySqlConnection; notice that the IsolationLevel of

Serializable is passed to BeginTransaction():

SqlTransaction serializableTrans =

mySqlConnection.BeginTransaction(IsolationLevel.Serializable);

The next example creates a SqlCommand named serializableCommand, and sets its Transaction property to serializableTrans:

SqlCommand serializableCommand =

mySqlConnection.CreateCommand();

serializableCommand.Transaction = serializableTrans;

Any SQL statements performed using serializableCommand will now use

serializableTrans, and will therefore be performed in a serializable transaction The following example performs an INSERT statement that adds a row to the Customers table:

serializableCommand.CommandText =

"INSERT INTO Customers ("+

"CustomerID, CompanyName "+

") VALUES ("+

"'J8COM', 'J8 Company' "+

")";

int numberOfRows = serializableCommand.ExecuteNonQuery();

The next example performs an UPDATE statement:

serializableCommand.CommandText =

"UPDATE Customers "+

"SET CompanyName = 'Widgets Inc.' "+

"WHERE CustomerID = 'ALFKI'";

numberOfRows = serializableCommand.ExecuteNonQuery();

Finally, the following example commits the INSERT and UPDATE statements by calling the Commit() method of serializableTrans:

serializableTrans.Commit();

Listing 14.4 shows a program that contains the following methods:

DisplayRows() Selects and displays any rows from the Customers table with a CustomerID of ALFKI or J8COM

Trang 7

PerformSerializableTransaction() Performs the code shown earlier in this section to create a SqlTransaction object with an isolation level of Serializable, and uses it to perform an INSERT and UPDATE statement

PerformReadCommittedTransaction() Creates a SqlTransaction object with an isolation level of ReadCommitted, and uses it to perform UPDATE and DELETE statements

Listing 14.4: TransactionIsolation.cs

/*

TransactionIsolation.cs illustrates how to set the

transaction isolation level

*/

using System;

using System.Data;

using System.Data.SqlClient;

class TransactionIsolation

{

public static void DisplayRows(

SqlCommand mySqlCommand

)

{

mySqlCommand.CommandText =

"SELECT CustomerID, CompanyName "+

"FROM Customers "+

"WHERE CustomerID IN ('ALFKI', 'J8COM')";

SqlDataReader mySqlDataReader = mySqlCommand.ExecuteReader();

while (mySqlDataReader.Read())

{

Console.WriteLine("mySqlDataReader[\" CustomerID\"] = "+

mySqlDataReader["CustomerID"]);

Console.WriteLine("mySqlDataReader[\" CompanyName\"] = "+

mySqlDataReader["CompanyName"]);

}

mySqlDataReader.Close();

}

public static void PerformSerializableTransaction(

SqlConnection mySqlConnection

)

{

Console.WriteLine("\nIn PerformSerializableTransaction()");

Trang 8

// create a SqlTransaction object and start the transaction

// by calling the BeginTransaction() method of the SqlConnection // object, passing the IsolationLevel of Serializable to the method SqlTransaction serializableTrans =

mySqlConnection.BeginTransaction(IsolationLevel.Serializable);

// create a SqlCommand and set its Transaction property

// to serializableTrans

SqlCommand serializableCommand =

mySqlConnection.CreateCommand();

serializableCommand.Transaction = serializableTrans;

// call the DisplayRows() method to display rows from

// the Customers table

DisplayRows(serializableCommand);

// insert a new row into the Customers table

Console.WriteLine("Inserting new row into Customers table "+ "with CustomerID of J8COM");

serializableCommand.CommandText =

"INSERT INTO Customers ("+

"CustomerID, CompanyName "+

") VALUES ("+

"'J8COM', 'J8 Company' "+

")";

int numberOfRows = serializableCommand.ExecuteNonQuery(); Console.WriteLine("Number of rows inserted = "+ numberOfRows);

// update a row in the Customers table

Console.WriteLine("Setting CompanyName to 'Widgets Inc.' for "+ "row with CustomerID of ALFKI");

serializableCommand.CommandText =

"UPDATE Customers "+

"SET CompanyName = 'Widgets Inc.' "+

"WHERE CustomerID = 'ALFKI'";

numberOfRows = serializableCommand.ExecuteNonQuery();

Console.WriteLine("Number of rows updated = "+ numberOfRows); DisplayRows(serializableCommand);

// commit the transaction

serializableTrans.Commit();

}

Trang 9

public static void PerformReadCommittedTransaction(

SqlConnection mySqlConnection

)

{

Console.WriteLine("\nIn PerformReadCommittedTransaction()");

// create a SqlTransaction object and start the transaction

// by calling the BeginTransaction() method of the SqlConnection // object, passing the IsolationLevel of ReadCommitted to the method // (ReadCommitted is actually the default)

SqlTransaction readCommittedTrans =

mySqlConnection.BeginTransaction(IsolationLevel.ReadCommitted);

// create a SqlCommand and set its Transaction property

// to readCommittedTrans

SqlCommand readCommittedCommand =

mySqlConnection.CreateCommand();

readCommittedCommand.Transaction = readCommittedTrans;

// update a row in the Customers table

Console.WriteLine("Setting CompanyName to 'Alfreds Futterkiste' "+ "for row with CustomerID of ALFKI");

readCommittedCommand.CommandText =

"UPDATE Customers "+

"SET CompanyName = 'Alfreds Futterkiste' "+

"WHERE CustomerID = 'ALFKI'";

int numberOfRows = readCommittedCommand.ExecuteNonQuery(); Console.WriteLine("Number of rows updated = "+ numberOfRows);

// delete the new row from the Customers table

Console.WriteLine("Deleting row with CustomerID of J8COM"); readCommittedCommand.CommandText =

"DELETE FROM Customers "+

"WHERE CustomerID = 'J8COM'";

numberOfRows = readCommittedCommand.ExecuteNonQuery(); Console.WriteLine("Number of rows deleted = "+ numberOfRows); DisplayRows(readCommittedCommand);

// commit the transaction

readCommittedTrans.Commit();

}

public static void Main()

Trang 10

{

SqlConnection mySqlConnection =

new SqlConnection(

"server=localhost;database=Northwind;uid=sa;pwd=sa"

);

mySqlConnection.Open();

PerformSerializableTransaction(mySqlConnection);

PerformReadCommittedTransaction(mySqlConnection);

mySqlConnection.Close();

}

}

The output from this program is as follows:

In PerformSerializableTransaction()

mySqlDataReader["CustomerID"] = ALFKI

mySqlDataReader["CompanyName"] = Alfreds Futterkiste

Inserting new row into Customers table with CustomerID of J8COM

Number of rows inserted = 1

Setting CompanyName to 'Widgets Inc.' for row with CustomerID of ALFKI Number of rows updated = 1

mySqlDataReader["CustomerID"] = ALFKI

mySqlDataReader["CompanyName"] = Widgets Inc

mySqlDataReader["CustomerID"] = J8COM

mySqlDataReader["CompanyName"] = J8 Company

In PerformReadCommittedTransaction()

Setting CompanyName to 'Alfreds Futterkiste' for row with CustomerID of ALFKI Number of rows updated = 1

Deleting row with CustomerID of J8COM

Number of rows deleted = 1

mySqlDataReader["CustomerID"] = ALFKI

mySqlDataReader["CompanyName"] = Alfreds Futterkiste

Ngày đăng: 21/01/2014, 07:20

TỪ KHÓA LIÊN QUAN

w