あなたの最初の質問に答えるために...
トランザクションを使用する場合、接続に関する限り、クエリは通常どおり実行されます。コミットするか、それらの変更を保存するか、ロールバックしてすべての変更を元に戻すかを選択できます。次の擬似コードを検討してください。
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()asid;'を使用できます。$ this-> db-> insert_id()関数ではなく。
2番目の質問に答えるために、他のモデルが更新または読み取るデータを挿入または更新する場合は、必ずトランザクションを使用してください。たとえば、列'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」を読み取ります(更新の選択
が使用さ れている場合、行はロックされます)個人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秒)に到達し、切断さ
れます行1で、通常どおり続行します
最後に、人物BはおそらくPHPに到達しているmax_execution_time
ため、現在のクエリはPHPとは独立して実行を終了しますが、それ以上のクエリは受信されません。これがautocommit=0のトランザクションであった場合、PHPサーバーへの接続が切断されると、クエリは自動的にロールバックされます。