开发者

How do I SELECT an un-referenced row from a table and lock it?

开发者 https://www.devze.com 2023-01-15 13:28 出处:网络
I have a table of chalets where a chalet is referenced by an acc开发者_如何学运维ount... CHALET

I have a table of chalets where a chalet is referenced by an acc开发者_如何学运维ount...

CHALET
------
int ChaletId PK
int Berth

ACCOUNT
-------
int AccountId PK
int ChaletId FK

The chalets start off un-referenced. When a user buys a chalet the code needs to find an unreferenced chalet and assign it to a newly created account. I think that the returned chalet needs to have an UPDLOCK on it until the account that will reference it has been commited in order to stop a concurrent shopper from being assigned the same chalet.

How can I write the SELECT that fetches a chalet? I was thinking something like this..

SELECT * FROM CHALET WITH (UPDLOCK) c
LEFT JOIN ACCOUNT a
ON c.ChaletId = a.ChaletID
WHERE a.ChaletID is null
AND Berth = 4

I think the problem is that if this query is being run concurrently then one query might lock half of one table and another might lock the other half and a dead lock would ensure. Is there a way around this? For example, is it possible to lock the selected chalet rows in the same orders?

Cheers, Ian.


Would (UPDLOCK, ROWLOCK, READPAST) do what you need?


I think you are trying to use SQL Concurrency locking when you really need your application to handle provisional reservations.

  • Create a flag column or separate table of the reservations that are in-flight.
  • Make all your other queries exclude items that are in the process of being reserved.
  • In the case of a rollback, you would need to unwind that reservation.


try

SELECT * FROM CHALET WITH (UPDLOCK, HOLDLOCK) c
LEFT JOIN ACCOUNT a
ON c.ChaletId = a.ChaletID
WHERE a.ChaletID is null
AND Berth = 4

But why oh why are you not using an identity property for this kind of stuff instead of trying to roll your own?

0

精彩评论

暂无评论...
验证码 换一张
取 消