1

私は次のように機能するトランザクションアプリケーションを持っています:

try {
     $db->begin();
     increaseNumber();
     $db->commit();
} catch(Exception $e) {
     $db->rollback();
}

そして、increaseNumber()内に、このようなクエリがあります。これは、このテーブルで機能する唯一の関数です。

// I use FOR UPDATE so that nobody else can read this table until its been updated
$result = $db->select("SELECT item1
FROM units
WHERE id = '{$id}'
FOR UPDATE");

$result = $db->update("UPDATE units SET item1 = item1 + 1
WHERE id = '{$id}'");

すべてがトランザクションにラップされていますが、最近、かなり遅いクエリを処理していて、アプリケーションで多くの同時実行が行われているため、クエリが特定の順序で実行されることを実際に確認することはできません。

デッドロックによりACIDトランザクションが中断する可能性はありますか?何かを追加する関数とそれを削除する関数がありますが、デッドロックがあると、トランザクションが無視されたように、データが完全に同期していないことがわかります。

これは必ず起こるのでしょうか、それとも何か問題がありますか?

ありがとう、ドミニク

4

2 に答える 2

2

トランザクションが解放されない(別のトランザクションからの)ロックに遭遇した場合、タイムアウト後に失敗します。デフォルトは30秒だと思います。誰かがデータベースでサードパーティのアプリケーションを使用しているかどうかをメモする必要があります。たとえば、SQL Manager 2007は、データベースから切断しない限りInnoDB のロックを解放しないことを知っています(場合によっては、コミットトランザクションのみが必要です)。これにより、多くのクエリが失敗します。タイムアウト。もちろん、トランザクションがACIDに準拠している場合は、オールオアナッシングで実行する必要があります。トランザクション間でデータを分割した場合にのみ破損します。

タイムアウトを延長してみることができますが、30秒のロックは、より深刻な問題を意味する場合があります。もちろん、使用しているストレージエンジンによって異なります(MySQLタグとトランザクションによって、InnoDBを想定しています)。

また、クエリプロファイリングをオンにして、クエリがばかげた時間実行されるかどうかを確認することもできます。もちろん、パフォーマンスが低下するため、本番ソリューションではない可能性があることに注意してください。

于 2011-07-13T08:07:02.493 に答える
1

ACIDのAはAtomicの略であるため、デッドロックによってACIDトランザクションが中断することはありません。むしろ、オールオアナッシングのように発生しないようになります。

多くの場合、データに一貫性がない場合、アプリケーションは論理的な単一のトランザクションで複数の「トランザクション」を実行します。たとえば、ユーザーが作成してアカウントを作成し(transaction-begin ..- commit)、ユーザーがパスワードを設定します(transaction-begin .. .-deadlock ..- rollback)アプリケーションはエラーを無視して続行します。これで、データベースにはユーザーが作成され、パスワードは残されません。

アプリケーションをロールバック以外にアプリケーションが実行していることと論理的に見て、一貫性のあるデータの構築に複数の部分があるかどうかを確認します。

于 2011-07-13T08:09:49.950 に答える