关于PHP / MySQL事务和SELECT FOR UPDATE的澄清

时间:2012-11-25 09:34:37

标签: php mysql transactions pdo locking

这是我的设置: 包含30分钟时隙(整个半小时)的MySQL数据库中的表 一个网站,显示一段时间表,每个时间段可预订多少房间。 最少预订是一小时,因此每个预订至少预留两个插槽,当预订时,他们之前的插槽将无法使用(无法预订房间30分钟)

我的问题是: 我在PHP脚本中使用PDO事务通过更改其状态(两列枚举类型)为预订保留多个插槽。因此,如果让我们说两个或更多的客户试图在同一时间段预订一个房间,或者可能是之前的一个房间,如果我使用SELECT FOR UPDATE会发生什么?第一个是继续执行该过程而其他人是否被拒绝(通过错误或空集)或者其他人在第一个完成后等待,并在他预订或回滚的情况下提交数据库中的更改他改变了主意,然后第二个最快的客户试图选择行并根据第一个行动更新它们?

基本上我想知道我是否必须实施某种重试系统。

另外,我很好奇是什么时候删除了临时锁;只有在事务(mysql,自动提交关闭)或下一次更新影响select语句中的部分/全部行时提交事务?

2 个答案:

答案 0 :(得分:0)

感谢所有帮助,我发现了类似here的内容,以及今后的访问者......

答案 1 :(得分:-1)

基本上,在PDO中,事务(以beginTransaction方法启动)只是通过将autocomit设置为false来“模拟”。 因此,即使选择更新的并发访问风险很小,也存在。

您可以使用SQL语句$db->query('START TRANSACTION')然后db->query('COMMIT');开始您的事务,当然,如果失败db->query('ROLLBACK'); 通常情况下,它可以让您避免出现问题。 如果您想确定,您可以在交易中使用$db->query('LOCK TABLE ...');

当您使用Transaction时,所有内容都会同时发送,这样您就不会在表中出现垃圾。 由于每个事务(默认情况下一个查询是一个事务)是一个接一个地执行,理论上,这可以保护您免受concurent访问。但问题是你使用SELECT进行更新,我认为当事务不能保护你时可能存在边缘情况,你会默默地删除另一个好的数据。

锁表对此非常有用,因为不允许使用任何边框。问题是,如果你保持锁太多时间,将发送错误。