2011-11-12 15 views
0

私は、MySQLデータベース上で多くの並列CRUD操作を実行するマルチスレッドのJavaアプリケーションを使用しています。 MySQLのマニュアルで読んでいるように、InnoDBのテーブル構造は、トランザクションがACID priciplesに従って実行されることを保証する必要があります。しかし、私はまだ問題があります。アップデートが失われることがあるためです。これは私が使用例ストアドプロシージャのいずれかです。マルチスレッド環境でのACIDの問題

DELIMITER // 
CREATE PROCEDURE *** (
    _*** INT, 
    _*** INT, 
    _*** INT, 
    _*** INT 
) 
BEGIN 
    START TRANSACTION; 

    UPDATE `***` 
    SET 
     `***`.`***` = `***`.`***` + _***, 
     `***`.`***` = `***`.`***` + _*** + _***, 
     `***`.`***` = DATE_ADD(NOW(), INTERVAL _*** SECOND) 
    WHERE `***`.`***` = _***; 

    COMMIT; 
END; 
// 
DELIMITER ; 
+1

ACIDのIの有害物質。トランザクションの分離は複雑な問題です。同じ行の同時更新を避けるために、トランザクション・レベルをシリアライズ可能に設定するか、いくつかの行ロックを設定してください。 – regilero

+0

@regilero:あなたは答えとしてそれを置くべきです! Vilius:これも読んでください:http://www.mpopp.net/2005/12/tx-isolation-levels-3-repeatable-read-serializable/ –

+0

私はこの記事とトランザクションレベルについての他の記事を読んだが、まだそれは私のために働かなかった...私はJavaアプリケーションの設計を代わりに再考し、MySQLサーバを5.5ブランチにアップデートする。 – Vilius

答えて

3

JDBCクラスはリエントラントではありませんので、あなたは、接続、ステートメントのオブジェクトインスタンスの使用を同期化する必要があり、など彼らはsavely複数のスレッドで使用することはできません同時に。

接続プールを使用すると、データベースへの同時アクセスを効率的に行うことができます。

編集

あなたはスレッドが同じ接続を使用しないことを確認している場合は、

  • プールは、接続の外にすることができを確認するだろうか?どのように処理されますか?
  • 2つの更新が、最初のレコードが上書きされる同じレコードで動作する可能性がありますか?
  • すべての例外をキャッチして、あなたのワーカーにログに記録しますか?
+0

悲しいことは、私がすでにConnection Pool(BoneCP)を使用していることです。私はまた、ThreadPoolExecutorを使って、SQL操作を実行するさまざまなスレッドを処理します。私は、これらの両方の技術がデータベースへのエラーのない同時アクセスを保証すると考えました。 – Vilius

+0

@Villius、編集を参照 – rsp

+0

提案ありがとうございます!私は基本的に2番目の箇条書きで問題が発生すると考えています...そのため、エラーはJava Connection Pool/ThreadExecutorではなくMySQL Serverで発生すると考えられます。私はまた、MySQL 5.5がInnoDBのロックをより良くサポートしていると聞きましたか?本当ですか? (私はまだ5.1.xを使用しています) – Vilius

関連する問題