17.06.2013 Views

Beginning Microsoft SQL Server 2008 ... - S3 Tech Training

Beginning Microsoft SQL Server 2008 ... - S3 Tech Training

Beginning Microsoft SQL Server 2008 ... - S3 Tech Training

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

Chapter 14: Transactions and Locks<br />

indeed be set to –25, even though it logically appeared that we prevented this through the use of our IF<br />

statement.<br />

We can prevent this problem in only two ways:<br />

❑ Create a CHECK constraint and monitor for the 547 Error.<br />

❑ Set our isolation level to be REPEATABLE READ or SERIALIZABLE.<br />

The CHECK constraint seems fairly obvious. The thing to realize here is that you are taking something of<br />

a reactive rather than a proactive approach with this method. Nonetheless, in most situations we have a<br />

potential for non-repeatable reads, so this would be my preferred choice in most circumstances.<br />

We’ll be taking a full look at isolation levels shortly, but for now, suffice it to say that there’s a good chance<br />

that setting it to REPEATABLE READ or SERIALIZABLE is going to cause you as many headaches as it<br />

solves (or more). Still, it’s an option.<br />

Phantoms<br />

436<br />

No, we’re not talking the of the Opera kind here — what we’re talking about are records that appear mysteriously,<br />

as if unaffected by an UPDATE or DELETE statement that you’ve issued. This can happen quite<br />

legitimately in the normal course of operating your system and doesn’t require any kind of elaborate<br />

scenario to illustrate. Here’s a classic example of how this happens.<br />

Let’s say you are running a fast food restaurant. If you’re running a typical establishment of that kind,<br />

you probably have a fair number of employees working at the minimum wage as defined by the government.<br />

The government has just decided to raise the minimum wage from $6.50 to $7.50 per hour, and you<br />

want to run an UPDATE on the EmployeePayHistory table to move anyone making less than $7.50 per<br />

hour up to the new minimum wage. “No problem,” you say, and you issue the rather simple statement:<br />

UPDATE HumanResources.EmployeePayHistory<br />

SET HourlyRate = 7.50<br />

WHERE HourlyRate < 7.50;<br />

ALTER TABLE Employees<br />

ADD ckWage CHECK (HourlyRate >= CONSTRAINT 7.50);<br />

GO<br />

That was a breeze, right? Wrong! Just for illustration, we’re going to say that you get an error message back:<br />

Msg 547, Level 16, State 1, Line 1<br />

ALTER TABLE statement conflicted with COLUMN CHECK constraint ‘ckWage’. The<br />

conflict occurred in database ‘AdventureWorks<strong>2008</strong>’, table ‘EmployeePayHistory’,<br />

column ‘Rate’.<br />

So you run a quick SELECT statement checking for values below $7.50, and sure enough you find one.<br />

The question is likely to come rather quickly, “How did that get there? I just did the UPDATE that should<br />

have fixed that!” You did run the statement, and it ran just fine — you just got a phantom.<br />

The instances of phantom reads are rare and require just the right circumstances to happen. In short,<br />

someone performed an INSERT statement at the very same time your UPDATE was running. Since it was<br />

an entirely new row, it didn’t have a lock on it and it proceeded just fine.

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!