大问题...
我正在用 PHP 和 MySQL 实现一个在线售票系统。我有一个名为“block_of_tickets”的表,或者类似的东西......
此表如下所示:
+-----------+------------+--------------+--------- -----+--------------+ | 标识块 | 块名 | 总票数| 块性别 | idblock_pair | +-----------+------------+--------------+--------- -----+--------------+ | 1 | 块 1- M | 100 | 男 | 2 | +-----------+------------+--------------+--------- -----+--------------+ | 2 | 1-F 座 | 100 | 女 | 1 | +-----------+------------+--------------+--------- -----+--------------+
在哪里:
- idblock:票块的id(主键)。
- block_name:块的名称。在示例中,我有一个“Block 1-M”和“Block 1-F”分别代表“Block 1 - Male”和“Block 1 - Female”。
- total_tickets:可用门票总数
- block_gender:票块的性别
- idblock_pair:当前块对的块。
注意:还有其他列,如“价格”等。
这是(大)问题:
当有“ idblock_pair ”时,这意味着两个票块将共享相同的total_tickets(可用票),因此在这种情况下两个单元格必须具有完全相同的值。正如您在上面的示例中看到的那样,块 1 指向块 2,反之亦然。
很多人(几乎)同时购买了很多票,这意味着每张售出的票必须在两个单元格的“total_tickets”字段中减 1。
数据库规范化可以解决这个问题。但是,它会在性能上损失很多。
我几乎可以肯定我应该使用“SELECT ... FOR UPDATE”...但我不知道如何,因为它是同一张表,并且可能会发生“死锁”...
如何解决这个问题呢?我必须使用触发器吗?程序?我必须使用 PHP 处理(和事务)来解决这个问题吗?
在下面的示例中,售出了一张票,现在我将total_tickets减1:
开始交易; 选择 * FROM block_of_tickets WHERE idblock in (1,2) FOR UPDATE; 更新 block_of_tickets SET total_tickets = (total_tickets - 1) WHERE idblock in (1,2); 犯罪;
这是一个很好的解决方案吗?