3

たとえば、ユーザーがリンクをクリックすると、新しい行が自動的に挿入され、次にphpコードが最後に挿入されたIDを要求し、同時に別のユーザーが別の行を挿入した場合、問題はありません。したがって、返されるIDは、実際には私が期待しているものではありません。

私が間違っている?その「セキュリティ」の穴なしで同じことをする方法はありますか?
(多分準備されたステートメントの中からか何かのように...)

PSIDは自動的に生成されます。

ありがとうございました。

4

3 に答える 3

5

マニュアルに記載されているように:

LAST_INSERT_ID()(引数なし)は、そのような列に影響を与えるために最後に実行されたステートメントによって列に設定された最初の自動生成値をBIGINT表す(64ビット)値を返します。たとえば、値を生成する行を挿入した後、次のような値を取得できます。AUTO_INCREMENT INSERTAUTO_INCREMENT

mysql>SELECT LAST_INSERT_ID();
    ->195

現在実行中のステートメントは、の値に影響を与えません LAST_INSERT_ID()AUTO_INCREMENT1つのステートメントで値を生成し、それから、独自の列を持つテーブルに行を挿入LAST_INSERT_ID()する複数行のステートメントで参照するとします。の値は、2番目のステートメントでも安定しています。2行目以降の値は、前の行の挿入の影響を受けません。(ただし、とへの参照を混在させると、効果は定義されません。)INSERTAUTO_INCREMENTLAST_INSERT_ID()LAST_INSERT_ID()LAST_INSERT_ID(expr)

前のステートメントがエラーを返した場合、の値 LAST_INSERT_ID()は未定義です。トランザクションテーブルの場合、エラーが原因でステートメントがロールバックされた場合、の値 LAST_INSERT_ID()は未定義のままになります。手動ロールバックの場合、の値は LAST_INSERT_ID()トランザクション前の値に復元されません。ROLLBACKの時点のままです。

したがって、LAST_INSERT_ID()(トランザクションを使用しない場合でも)常にトランザクションセーフです。

于 2012-07-10T11:32:25.913 に答える
4

MySQLサーバーはOK、成功した後、メッセージの一部として挿入IDを転送しINSERTます。このIDはPDOに保存されるため、サーバーへのラウンドトリップなしで、PDOは安全な方法で接続用の正しいIDを返すことができます。

参照: http: //forge.mysql.com/wiki/MySQL_Internals_ClientServer_Protocol#OK_Packet

于 2012-07-10T12:35:08.197 に答える
3

これに対抗するには、トランザクションを使用します。

lastInsertId()これにより、挿入が他の挿入から本質的に分離され、挿入/呼び出しが同じトランザクション内にある限り、問題なく機能します。

于 2012-07-10T11:06:39.213 に答える