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?
精彩评论