我正在制作一款抽奖游戏,有人建议我从MyISAM转换到InnoDB并开始使用FOR UPDATE
,这样彩票(范围为1-16)就不会被重复售出。
现在我想知道,FOR UPDATE
是如何工作的。
我在网上看到类似以下内容:
SELECT * FROM [table] WHERE [column] = [value] FOR UPDATE
UPDATE [table] SET [column] = [new_value]
然而,我的问题是关于以下内容的:它是否也适用于 INSERT
?
我的数据库设计:
CREATE TABLE IF NOT EXISTS `Lottery` (
`id` varchar(50) NOT NULL,
`preferedLotteryId` varchar(50) NOT NULL,
`winningTicketId` int(11) NOT NULL DEFAULT '-1',
`createdOn` datetime NOT NULL DEFAULT '1001-00-00 00:00:00',
`startedOn` datetime NOT NULL DEFAULT '1001-00-00 00:00:00',
`finishedOn` datetime NOT NULL DEFAULT '1001-00-00 00:00:00',
`active` tinyint(1) NOT NULL,
`deliveredOn` datetime NOT NULL DEFAULT '1001-00-00 00:00:00',
`preferedDeliverMethod` int(2) NOT NULL DEFAULT '-1',
`deliveredMethod` int(2) NOT NULL DEFAULT '-1',
`deliveredByAccountId` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `LotteryBid` (
`bidId` varchar(50) NOT NULL,
`accountId` varchar(50) NOT NULL,
`auctionId` varchar(50) NOT NULL,
`ticketId` int(50) NOT NULL,
`datetime` datetime NOT NULL DEFAULT '1001-00-00 00:00:00',
PRIMARY KEY (`bidId`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
这意味着这个设计需要类似于 FOR UPDATE
的东西:
SELECT * FROM Lottery WHERE id = [id] FOR UPDATE
INSERT INTO LotteryBids SET [LotteryBids.values & Lottery.id]
或者SELECT * FROM Lottery WHERE id = [id] FOR UPDATE
INSERT INTO LotteryBids, Lottery SET [LotteryBids.values] WHERE Lottery.id = [id]
然而,我不知道使用 FOR UPDATE
的方式是否可行。
我对这种大规模数据交互相当陌生,不知道该从哪里开始。
希望你们中的一些人能够帮助我。
顺颂时祺, Larssy1
我认为以下想法可能会转化为解决方案:
想法1:
一个用户正在购买彩票,其彩票ID为5。目前此彩票已售出3张,因此我想锁定此彩票的行数,直到我完成此插入操作为止。
想法2:
一个用户正在购买彩票,其彩票ID为5。目前此拍卖没有彩票与彩票ID 5相对应,因此我想预留一个类似拍卖ID和彩票ID的条目,并防止进一步添加,直到此查询完成。
使用的查询
选择一个彩票(包括附加信息):
SELECT au.*, asp.* FROM Lottery au, LotteryPrefered asp
WHERE au.preferedAuctionId = asp.id AND au.id = '" . $_auctionId . "'
或(不包括额外信息)
SELECT au.* FROM Lottery au
WHERE au.id = '" . $_auctionId . "'
购买门票:INSERT INTO LotteryBids (bidId, accountId, auctionId, ticketId, datetime)
VALUES ('" . $guid . "', '" . $_accountId . "', '" . $_auctionId . "',
'" . $_ticketId . "', NOW())
INSERT
语句是伪代码,但是WHERE
子句在INSERT
语句中会起到什么作用? - Marcus AdamsFOR UPDATE
发送一个小的“敲击”,表示已经发生了“更新”。但我不知道它实际上是如何工作的。 - larssy1