回答你的第一个问题...
使用事务时,就您的连接而言,您的查询会正常执行。您可以选择提交、保存这些更改,或回滚、恢复所有更改。考虑以下伪代码:
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 读取“1”
剩余数量
(该行现在被锁定,如果选择更新 http://dev.mysql.com/doc/refman/5.6/en/innodb-locking-reads.html用来)
乙人
尝试读取 Number_remaining - 被迫等待
A 获胜
1000 美元
A 将 1 更新为 0
A 人承诺
乙人
读取 0
B 没有赢得 1000 美元
B 人哭了
您可能想阅读事务隔离级别 http://dev.mysql.com/doc/refman/5.6/en/set-transaction.html以及。
请小心死锁,这种情况可能会发生:
A 读取第 1 行(select ... for update
)
B 人读行
2(select ... for update
)
A 尝试读取第 2 行,
被迫等待
B 尝试读取第 1 行,被迫等待
A 人到达innodb_lock_wait_timeout http://dev.mysql.com/doc/refman/5.0/en/innodb-parameters.html#sysvar_innodb_lock_wait_timeout(默认 50 秒)并且是
断开连接
B 读取第 1 行并正常继续
最后,由于 B 可能已经达到了 PHP 的水平max_execution_time
,当前查询将独立于 PHP 完成执行,但不会收到进一步的查询。如果这是一个 autocommit=0 的事务,则当与 PHP 服务器的连接被切断时,查询将自动回滚。