简体   繁体   中英

Simultaneous conflicting update queries

I feel like this is a fairly common scenario, though I haven't been able to find a solution that directly addresses this issue.

Consider the table below:

Username           HatSize

Tim                4  
Julie              3   
Mark               3
Susan              4

Let's say that I entered the values in to the "Hat Size" column incorrectly. I want to update the table so that a HatSize of 4 becomes 3 and a HatSize of 3 becomes 4 (effectively swapping the values of 3 and 4), like in the table below:

Username           HatSize

Tim                3  
Julie              4   
Mark               4
Susan              3

If I were to run a simple update query:

UPDATE table SET HatSize = '3' WHERE HatSize = '4'
UPDATE table SET HatSize = '4' WHERE HatSize = '3'

It would just make all the values in the HatSize column 4. I considered running it as a transaction, but I can't seems to find anything that suggests that running concurrent update queries like the ones above would work correctly.

I realize that I could use an intermediary value, but is there a more elegant way to achieve something like this?

UPDATE table 
   SET HatSize = CASE 
                      WHEN HatSize = '3' THEN '4'
                      WHEN HatSize = '4' THEN '3'
                 END

SQL FIDDLE

I know one technique for dealing with conflicting changes called optimistic concurrency.

You can create a Timestamp column in your table that changes to the current time automatically every time a row is updated.

Suppose you have a client that pulled in information from a row of this table, changed some of it, and tried writing the row values back to the database. In the update query's "WHERE" clause, update only rows where the timestamp is equal to the timestamp that the client originally pulled in. The client's timestamp value should be the same as the value currently in the row. If it isn't, the update query will affect 0 rows. This is when a concurrency exception should be thrown.

Then you'd catch the exception, update the values for the client that is trying to make changes, and inform them that someone else updated that record.

What flavor of SQL are you using? I would use a temp able to keep track of all the records for one of the values. In MS SQL:

INSERT Username
INTO #tmp
FROM TableName
WHERE HatSize='3'

UPDATE TableName SET
   HatSize=3
WHERE HatSize=4

UPDATE TableName SET
   HatSize=4
WHERE Usernaem IN (SELECT UserName FROM #tmp)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM