MySQL销售数据库一致性:排队交易?



我正在尝试创建一个能够销售礼品卡的应用程序,但我担心数据的一致性,所以让我解释一下我的意思:

我有3张桌子

事务(ID, created_date(,

卡(身份证、姓名(

凭证(身份证、代码、card_id、transaction_id(。

该数据库包含许多卡和凭证,每张凭证属于一张卡。 用户将希望选择要购买的卡并选择数量。

因此,应用程序将根据所选卡选择代金券,并根据数量选择LIMIT,然后创建新交易并将transaction_id添加到所选代金券中,以将其标记为此新交易的已购买卡。

那么,我担心的是,如果多个用户在同一时间为同一张卡发送相同的购买请求,那么会发生一些数据冲突吗? 解决这个问题的最佳方法是什么?

我目前正在为所有表使用带有InnoDB引擎的MySQL 8社区版。

我正在寻找的是,我是否可以创建某种队列,该队列可以一个接一个地激活交易而不会发生冲突,即使这意味着用户必须等到轮到他们进入队列。

提前致谢

这是MySQL事务的工作。 使用SQL,您可以执行类似操作。

START TRANSACTION;
SELECT id AS card_id FROM cards WHERE name = <<<<chosen name>>>> FOR UPDATE;
--do whatever it takes in SQL to complete the operation
COMMIT;

多个 php 进程可能会尝试同时使用同一行cards执行某些操作。将START TRANSACTIONSELECT ... FOR UPDATE结合使用将通过使下一个进程等到第一个进程COMMIT来防止这种情况。

在内部,MySQL有一个等待进程的队列。 只要您在执行BEGIN TRANSACTION后立即执行COMMIT,您的用户就不会注意到这一点。这通常不是在应用程序级别称为"排队",而是称为事务一致性。

Laravel/雄辩使这变得超级容易。它为您完成START TRANSACTIONCOMMIT,并提供lockForUpdate()

DB::transaction(function() {
DB::table('cards')->where('name', '=', $chosenName)->lockForUpdate()->get();
/* do whatever you need to do for your transaction */
});

最新更新