2012-05-05 21 views
0

PHPを使用して自分のプロジェクトでSQL文を実行するためにbeginTransaction()を使用しようとしました。私はデータベースに書き込まれる必要があるアイテムの配列を持っているし、各アイテムは何かに対して格納される前に検証する必要があります。データベースの自動コミット動作を無効にすることについての良い点の1つは、途中で何か問題が生じた場合にトランザクション全体をロールバックできることです。私のプロジェクトでは、1つの項目が無効な場合、配列全体をデータベースに記録すべきではないため、このアプローチを使用することにしました。ロールバックはパフォーマンスを改善しますか?

これは実際にパフォーマンスの面で優れているのかどうか疑問に思っています。配列の最後の項目が検証されても、前の実行を手動でcommit()する必要があるからです。コミットはSQLの実行を繰り返しますか?

今私が考えることができる唯一の利点は、すべての項目を有効にして(すべての項目が有効であると仮定して)それらを検証し、それぞれを書きたい場合は2つではなく1つのループを実行するだけです。

+4

SQLはデータベース製品ではありません。これは、多くのRDBMSで使用されている言語です。どのデータベースシステムを使用していますか、どのバージョンですか? – Ben

+0

@Ben、postgresql – Michael

+0

わずかにOT:データベースの状態と変更自体を調べることによって変更の有効性を判断できる場合は、おそらく検証をBEFOREトリガーに入れてビジネスロジックが使用されるアプリケーションコードのクライアントに関係なく適用されます。 – kgrittn

答えて

0

コミットはSQL実行を繰り返さない。

通常、トランザクションで作業する場合、INSERT/UPDATE/DELETEステートメントを実行するたびに、データベースはレコード/データページのコピーをトランザクションログに取り込み、実際のレコード変更を実行します。

トランザクション中に誰かがレコード/データページにアクセスしようとすると、トランザクションログのコピーにリダイレクトされます。

コミットを実行すると、データベース自体のデータはすでに更新されており、すべてのサーバーが行う必要があるのはトランザクションログの削除です。

コミットするのではなくロールバックすると、データベースサーバーはトランザクションログをバックトラックし、更新したすべてのレコード/データページを元の状態に戻し、各トランザクションログエントリを削除します。

したがって、ロールバックはオーバーヘッドです。これは、データベースサーバーがデータをトランザクション前の状態に復元する必要があるためです。

+3

ロールバックの実装に関するこの説明は、PostgreSQLには適用されません。 PGでは、更新前のレコードはどこにもコピーされません。トランザクションIDを持つ行が最新であるかどうかは、システムが任意の時点で認識します。オーバーヘッドは主に将来のある時点で、これらの未使用バージョンの行で使用されるディスク領域を再利用するためにVACUUMを実行する必要がありますが、コミットとロールバックの両方に当てはまります。 –

+0

私は、PostgreSQLタグを紛失していました。 –

+0

Danielは、PostgreSQLのロールバックがすばらしく速いと述べました。 – Kuberchaun

2

最初にすべてを検証し、トランザクションとデータベースのやりとりを開始します。データの検証を支援するためのトランザクションは行われません。

+0

私が言ったように、すべてを最初に検証したら、すべてがうまくいくと仮定して、配列をループして各アイテムをdbに書き込む必要があります。 – Michael

+0

これは一般的には悪い考えです。トランザクションが始まる前のある時点で何か*真だったからといって、データベース自体の外で同期が取られていない限り、トランザクションを適用するにはまだ*真であることを証明していません。トランザクションとは、並行変更が発生してもデータベースの整合性を保証できるメカニズムのことです。 – kgrittn

0

セーブポイントを使用できます。 manualから:

BEGIN; 
    INSERT INTO table1 VALUES (1); 
    SAVEPOINT my_savepoint; 
     INSERT INTO table1 VALUES (2); 
    ROLLBACK TO SAVEPOINT my_savepoint; 
    INSERT INTO table1 VALUES (3); 
COMMIT; 

あなたはまだあなたの入力を検証する必要がありますが、あなたが今、単一のトランザクション内でロールバックすることができます。トランザクションを使用すると、コミットが少ない(暗黙的に)ため、データベースが高速になります。

+0

+1 - 遠くに行くとトランザクションが非常に長くかかり、コースの多くのテーブルをロックし、必要以上に多くの並行操作をブロックし始める場合を除きます。次に、小さなトランザクションに分割する必要があります(スマートな方法で)。 –

+0

いつものように、それはあなたの仕事量によって異なります。 –

+0

質問では、いずれかの項目が妥当性検査に失敗した場合、それらのどれも適用されないことが明示されています。この提案は完全に反生産的です。 – kgrittn

関連する問題