我有一个简单的拆分测试表:
CREATE TABLE `tracked_split_test_track_variant` (
`tracked_split_test_id` int(10) unsigned NOT NULL,
`track_id` bigint(20) unsigned NOT NULL,
`variant` char(1) NOT NULL,
PRIMARY KEY (`tracked_split_test_id`,`track_id`),
KEY `tracked_split_test_track_variant_1` (`tracked_split_test_id`),
KEY `tracked_split_test_track_variant_2` (`track_id`),
CONSTRAINT `fk_tracked_split_test_track_variant_2`
FOREIGN KEY (`track_id`)
REFERENCES `track` (`id`)
ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `fk_tracked_split_test_track_variant_1`
FOREIGN KEY (`tracked_split_test_id`)
REFERENCES `tracked_split_test` (`id`)
ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8
其中变体是随机的A或B.
当系统询问“我应该向哪个用户显示该用户?”时我希望发生以下事情:
SELECT
属于当前tracked_split_test_track_variant
和track
的{{1}} tracked_split_test
目前,我在事务中运行INSERT
和(可选)SELECT
查询:
INSERT
和
SELECT *
FROM tracked_split_test_track_variant
WHERE track_id = :track_id
AND tracked_split_test_id = :tracked_split_test_id
FOR UPDATE
我已将 INSERT
INTO tracked_split_test_track_variant
VALUES (:track_id, :tracked_split_test_id, :variant)
添加到FOR UPDATE
,以便如果两个事务以相同的详细信息运行..我不会尝试两次SELECT
。
即使我尽快承诺,我现在也会陷入僵局。我做错了吗?
答案 0 :(得分:0)
由于元组在此事务之外是不可变的,因此我使用显式命名锁来提出以下解决方案:
SELECT GET_LOCK('tracked_split_test_track_variant-xxx-yyy',30);
SELECT *
FROM tracked_split_test_track_variant
WHERE tracked_split_test_id = :tracked_split_test_id
AND track_id = :track_id
[
INSERT
INTO tracked_split_test_track_variant
VALUES (:track_id, :tracked_split_test_id, :variant)
]
DO RELEASE_LOCK('tracked_split_test_track_variant-xxx-yyy');
其中xxx
是tracked_split_test_id
而yyy
是track_id
我很想知道是否有更好的解决方案。