3

私はこれに対する答えを見つけるために一日の大部分を費やしましたが、そこには1つがないようです。テーブルに行を作成し、挿入された行から自動インクリメントを取得し、その値を使用して2番目のテーブルに別の行を挿入する関数が必要です。次のphpに機能的に似ているもの:

$mysql_query("INSERT INTO table1 SET columns='values'");
$id = mysql_insert_id();
$mysql_query("INSERT INTO table2 SET id='$id', columns='values'");

私が遭遇している問題は、私のアプリケーションでは、単一のMySQL接続がすべてのクラス間で共有されているため、別のクラスが1行目と2行目の実行の間に行を挿入する競合状態が発生する可能性があることです。上記の。

私が思いつくことができる最も簡単な解決策はmysql_insert_id()、新しい独自の接続を使用する関数を使用することですが、それは膨大な量の不要なオーバーヘッドのようです。私が試した他の答えには、一意の値(おそらくで作成されたUUID())を挿入し、自動インクリメント値の代わりにそれを使用するか、最初の挿入と呼び出しをLAST_INSERT_ID()ストアド関数に入れることが含まれます(確かではありませんが)それが可能な競合状態を解決するかどうか)。

mysql_insert_id()また、トランザクションが役立つかどうかを確認するためにトランザクションを調べてきましたが、トランザクションとの正確な相互作用に関するドキュメントはほとんどありません。私が知る限りINSERT、トランザクションのロックのいずれとも競合しなかった別のものは実行でき、同じ競合状態を引き起こす可能性があるため、おそらくここでは役に立ちません。

それで、私が上記のいずれかに誤りがないと仮定して(そして私が誤りである場合は私を訂正してください)、2番目INSERTが適切な値を使用することを100%保証するための最良の方法は何ですか?

4

2 に答える 2

7

phpスクリプトの実行は線形であり、マルチスレッドではありません。
したがって、あるオブジェクトが別のオブジェクトと同時に実行されている場合に条件を設定することは不可能です。

考えられる唯一の問題は、持続的接続にある可能性があります。しかし、とにかく2つの別々の呼び出しで同じ接続を使用することはできないようです。永続的なものであっても、すでに使用されている場合は、別のスクリプトで使用することはできません。したがって、問題もありません。

于 2012-01-09T22:58:42.083 に答える
0

条件付きの場合に使用してみてください

if(mysql_query(query)){
    $id = mysql_last_id();
    mysql_query(query using $id);
}
于 2014-06-13T16:29:39.980 に答える