要回答你的第一个问题...
使用事务时,就您的连接而言,您的查询会正常执行。您可以选择提交、保存这些更改,或者回滚、还原所有更改。考虑以下伪代码:
insert into number(Random_number) values (rand());
select Random_number from number where Number_id=Last_insert_id();
//php
if($num < 1)
$this->db->query('rollback;'); // This number is too depressing.
else
$this->db->query('commit;'); // This number is just right.
生成的随机数可以在提交之前读取,以确保它在保存之前适合所有人查看(例如,提交和解锁行)。
如果 PDO 驱动程序不起作用,请考虑使用 mysqli 驱动程序。如果这不是一个选项,您始终可以使用查询“select last_insert_id() as id;” 而不是 $this->db->insert_id() 函数。
要回答您的第二个问题,如果您要插入或更新其他模型将要更新或读取的数据,请务必使用事务。例如,如果将“Number_remaining”列设置为 1,则可能会出现以下问题。
Person A reads 1
Person B reads 1
Person A wins $1000!
Person A updates 1 to be 0
Person B wins $1000!
Person B updates 0 to be 0
在相同情况下使用事务将产生以下结果:
人 A 开始事务
人 A 从 Number_remaining 读取“1” (如果使用select for update
,则 该行现在被锁定)人 B 尝试读取 Number_remaining - 被迫等待人 A 赢得 $1000人 A 将 1 更新为 0人 A 提交人B 读到 0人 B 没有赢得 $1000人 B 哭
您可能还想阅读事务隔离级别。
小心死锁,在这种情况下可能会发生:
A 读取第 1 行 ( select ... for update
)
B 读取第 2 行 ( select ... for update
)
A 尝试读取第 2 行,被迫等待
B 尝试读取第 1 行,被迫等待
A 达到innodb_lock_wait_timeout(默认 50 秒)并断开连接
B 读取第 1 行并正常继续
最后,由于 Person B 可能已经到达 PHP 的max_execution_time
,当前查询将独立于 PHP 完成执行,但不会收到进一步的查询。如果这是一个 autocommit=0 的事务,当与您的 PHP 服务器的连接被切断时,查询将自动回滚。