SELECT,如果满足条件,检查并插入
SELECT, check and INSERT if condition is met
我有以下表格:Tour、Customer、TourCustomerXRef。假设每个 Tour 都有容量上限。现在一个预订请求到达后端。
我需要做的是:
- SELECT 和 count() TourCustomerXRef 中的所有条目,其中 tourid=123
- 在程序代码(或查询?)中:如果 count() < Cap
- 正确: 插入 TourCustomerXRef,return 成功
- 错误: return 错误
但是,后端 api 有可能被同时调用。这可能会导致 SELECT 语句 returning 一个低于最大值的数字。 capacity 两次,导致 INSERT 被执行多次(即使只剩下一个地方)。
对于上述情况,最好的预防措施是什么?设置事务隔离级别可序列化?或可重复读取?
我担心应用程序逻辑(即使它只是一个简单的 if)可能会损害性能,因为读写锁不允许 api 执行只想 select 数据没有插入任何东西,对吧?
(使用 mariaDB)
您可以尝试在 SELECT(mysql 示例)中使用锁定提示 "FOR UPDATE":
BEGIN TRANSACTION;
SELECT * FROM TourCustomerXRef FOR UPDATE WHERE ...;
INSERT ...;
COMMIT;
我有以下表格:Tour、Customer、TourCustomerXRef。假设每个 Tour 都有容量上限。现在一个预订请求到达后端。
我需要做的是:
- SELECT 和 count() TourCustomerXRef 中的所有条目,其中 tourid=123
- 在程序代码(或查询?)中:如果 count() < Cap
- 正确: 插入 TourCustomerXRef,return 成功
- 错误: return 错误
但是,后端 api 有可能被同时调用。这可能会导致 SELECT 语句 returning 一个低于最大值的数字。 capacity 两次,导致 INSERT 被执行多次(即使只剩下一个地方)。
对于上述情况,最好的预防措施是什么?设置事务隔离级别可序列化?或可重复读取?
我担心应用程序逻辑(即使它只是一个简单的 if)可能会损害性能,因为读写锁不允许 api 执行只想 select 数据没有插入任何东西,对吧?
(使用 mariaDB)
您可以尝试在 SELECT(mysql 示例)中使用锁定提示 "FOR UPDATE":
BEGIN TRANSACTION;
SELECT * FROM TourCustomerXRef FOR UPDATE WHERE ...;
INSERT ...;
COMMIT;