1. Trang chủ
  2. » Thể loại khác

OReilly Programming Dot NET Windows Applications Oct 2003 ISBN 0596003218

31 37 0

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

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 31
Dung lượng 156,97 KB

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

Nội dung

In the previous section, you read data from the database into aDataSet, updated the data in the DataSet, and then wrote thechanges back to the database.. When one user works with a recor

Trang 1

In the previous section, you read data from the database into aDataSet, updated the data in the DataSet, and then wrote thechanges back to the database In a real-world application, itwould be possible for other people to read the same data into

DataSets of their own, edit their data, and write their changes

back to the database

You can easily imagine that this possibility could possibly causetremendous data corruption Imagine, for example, that a

quality assurance person downloads the current open bugs with

an eye toward updating some of the information Meanwhile,across the office (or across town) a developer has downloadedand is reviewing a few open bugs Both of them are reading bug

Trang 2

was Jesse and the Severity was High These earlier values arewritten over the values updated by QA, and the QA edits are

lost The technical term for this is bad.

To prevent this kind of problem, use any of the following

strategies:

1 Lock the records When one user works with a record, other users can read the records but cannot update them.

locked, but many surrounding records are locked as well

While record and page locking is not uncommon in some

database environments, it is generally undesirable It's possiblefor a record to be locked, and the user never to return to thedatabase to unlock it (if the user goes to lunch or her computer

Trang 3

processes that keep track of how long records have been

locked, and unlock records after a time-out period

As you saw in the previous example, a single query may touchmany records in many tables If you were to lock all those

records for each user, it wouldn't take long before the entiredatabase was locked In addition, it often isn't necessary Whileeach user may look at dozens of records, each user usuallyupdates only a very few Locking is a very big, blunt weapon;what is needed is a small, delicate surgical tool

The value that is now in the DataSet because you havechanged it

The DataSet provides support for this approach even though it

is not an efficient way to manage data updates This approachinvolves creating an event handler for the RowUpdating event.The event handler examines the original value of each field andqueries the database for the value currently in the database Ifthese values are different, then someone has changed the

database since the DataSet was filled, and you can take

corrective action

You will find two significant problems with this approach First,

Trang 4

This approach is very efficient In most cases, your update willsucceed, and you will not have bothered with extra reads of thedatabase If your update succeeds, there is no lag between

checking the data and the update, so there is no chance of

someone sneaking in another write Finally, if your update fails,you know why, and you can take corrective action

For this approach to work, your stored procedure for updatesmust fail if the data has changed in the database since the timeyou retrieved the DataSet Since the DataSet can tell you theoriginal values it received from the database, you can pass

those values back into the stored procedure as parameters, andthen add them to the Where clause in your update statement,

as shown in the spUpdateBugFromDataSetWithConcurrencystored procedure listed in Example 20-14

Example 20-14 Updating with concurrency

CREATE PROCEDURE spUpdateBugFromDataSetWithConcurrency

@ProductID int,

Trang 6

BugHistory table

The transaction tests for errors If no rows match, there is no error and the transaction will continue You must make sure that at least one row was added to Bugs before updating the BugHistory.

You can test for how many rows were added altogether in the

RowUpdated event handler If no row was updated, you can

assume that it was because the original row was changed, andyou can take appropriate corrective action

Trang 7

It is possible for the update to Bugs to work, yet the update to BugHistory fails The program will return one updated record For simplicity, this example does not handle that permutation A well- crafted update statement could catch this problem, but at the cost of making the code more difficult to understand.

The complete listing is shown in Example 20-15 for C# and

Trang 10

string cmd = "Update Bugs set Product = 2 where BugID = 1";

Trang 11

param.SourceVersion=DataRowVersion.Original;

param =

Trang 12

updateCmd.Parameters.Add("@Description",SqlDbType.Text,8000); param.Direction = ParameterDirection.Input;

Trang 14

param.SourceColumn="BugHistoryID";

param.SourceVersion=DataRowVersion.Original; // note Original

Trang 16

// as a string

string s = "Attempted " +

Trang 22

param = updateCmd.Parameters.Add("@OldReporter", SqlDbType.Int) param.Direction = ParameterDirection.Input

param.SourceColumn = "StatusID"

param.SourceVersion = DataRowVersion.Original

param = updateCmd.Parameters.Add("@Severity", SqlDbType.Int) param.Direction = ParameterDirection.Input

param.SourceColumn = "SeverityID"

param.SourceVersion = DataRowVersion.Current

param = updateCmd.Parameters.Add("@OldSeverity", SqlDbType.Int) param.Direction = ParameterDirection.Input

param.SourceColumn = "SeverityID"

param.SourceVersion = DataRowVersion.Original

Trang 23

param.SourceColumn = "BugHistoryID"

param.SourceVersion = DataRowVersion.Original ' note Original

param = deleteCmd.Parameters.Add("@BugHistoryID", SqlDbType.Int) param.Direction = ParameterDirection.Input

param.SourceColumn = "BugHistoryID"

param.SourceVersion = DataRowVersion.Original ' note Original

Trang 26

System.Enum.GetName(e.StatementType.GetType( ), e.StatementType) & _ " "

Trang 29

MessageBox.Show(s & "Concurrency error updating BugID: " & _ e.Row("BugID", DataRowVersion.Original))

Trang 30

string cmd = "Update Bugs set Product = 2 where BugID = 1";SqlCommand cmd1 = new SqlCommand(cmd,connection2);

cmd1.ExecuteNonQuery( );

Dim myConnection2 As _

New System.Data.SqlClient.SqlConnection(connectionString)myConnection2.Open( )

Trang 31

field in Bugs rather than in BugHistory In previous examples, you wrote:

bugTable.Rows[0]["Response"] =

"This is a test";

In this example, you will modify it to:

bugTable.Rows[0]["ReporterID"] = "1";

Ngày đăng: 26/03/2019, 17:14