如何从表中选择未引用的行并锁定它?

发布于 2024-09-18 22:04:59 字数 563 浏览 8 评论 0原文

我有一张小木屋表,其中的小木屋由帐户引用...

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

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

小木屋一开始没有引用。当用户购买小木屋时,代码需要找到未引用的小木屋并将其分配给新创建的帐户。我认为返回的小木屋需要有一个 UPDLOCK,直到引用它的帐户已被提交,以阻止并发购物者被分配到相同的小木屋。

我如何编写获取小木屋的 SELECT 语句?我在想这样的事情..

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

我认为问题是,如果这个查询同时运行,那么一个查询可能会锁定一个表的一半,而另一个查询可能会锁定另一半,从而确保死锁。有办法解决这个问题吗?例如,是否可以以相同的顺序锁定选定的小屋行?

干杯,伊恩。

I have a table of chalets where a chalet is referenced by an account...

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

錯遇了你 2024-09-25 22:05:00

(UPDLOCK, ROWLOCK, READPAST) 做你需要做的事情< /a>?

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

冷血 2024-09-25 22:05:00

我认为当您确实需要应用程序处理临时保留时,您正在尝试使用 SQL 并发锁定。

  • 创建正在进行的预订的标志列或单独的表。
  • 让您的所有其他查询排除正在预订的项目。
  • 在回滚的情况下,您需要取消该预留。

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.
夜雨飘雪 2024-09-25 22:05:00

尝试

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

但是为什么哦为什么你不使用这种东西的身份属性而不是尝试推出自己的身份属性?

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?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文