Mysqlデータベースの同時挿入デッドロックの問題と処理方法

3141 ワード

Mysqlには穴がたくさんありますが、Mysqlマルチスレッドサポートに慣れていないとわけがわからず奇妙な問題が発生します.マルチスレッドスレッドが同時に動作する場合、デッドロックの問題が最も発生しやすい.そのため、多くのビッグデータの操作は一般的にNoSQLデータベースの方案を採用して処理したり、読み書きを分離したりして、べき乗などの設計をするだけでいいです.
データベースの同時実行を回避する方法
1.データベース接続プールによる配布:データベース接続プールのパラメータを設定します.
構成:スレッドプールサイズ、アイドル時間、タイムアウト時間など.
2.スレッドを手動で開いてデータを挿入しない:スレッドを手動で開いて一括挿入を実行しない.
new Thread(new Runnable(){ public void run(){//       }}).start(); //          
3.スレッドを実行するときは、Threadを直接使用するのではなく、スレッドプールをできるだけ使用します.
package com.boonya.thread;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

class TaskRunnable implements Runnable {
    @Override
    public void run() {
        for (int x = 0; x < 100; x++) {
          Thread.sleep(1000);//  1000ms
         System.out.println("Do something:"+x);
       }
    }
}

public class ExecutorServiceDemo {
    public static void main(String[] args) {
     //          ,           。
     // public static ExecutorService newFixedThreadPool(int nThreads)
     ExecutorService pool = Executors.newFixedThreadPool(2);

     //     Runnable    Callable       
     pool.submit(new TaskRunnable ());
     pool.submit(new TaskRunnable ());

    //     
    pool.shutdown();
   }
}

注意:上記のスレッドプールの例は、主にシステムリソースの使用量を節約するためです.
デッドロックの問題の処理方法
Mysql挿入問題の説明:INSERT sets an exclusive lock on the inserted row.This lock is an index-record lock, not a next-key lock (that is, there is no gap lock) and does not prevent other sessions from inserting into the gap before the inserted row.Prior to inserting the row, a type of gap lock called an insertion intention gap lock is set. This lock signals the intent to insert in such a way that multiple transactions inserting into the same index gap need not wait for each other if they are not inserting at the same position within the gap.If a duplicate-key error occurs, a shared lock on the duplicate index record is set. This use of a shared lock can result in deadlock should there be multiple sessions trying to insert the same row if another session already has an exclusive lock.一般的には、insertは、next-keyロックではなく、正常に挿入されたローに排他的なロックを追加します(もちろんgapロックではありません).他の同時トランザクションがこのレコードの前にレコードを挿入することを阻止することはありません.挿入する前に、挿入レコードがある隙間に挿入意向gapロック(Iロックと略称)を追加し、同時トランザクションで同じgapにIロックを追加することができます.insertのトランザクションにduplicate-key errorが発生した場合、トランザクションはduplicate index recordに共有ロックを追加します.この共有ロックは、同じレコードに共有ロックを追加する2つの同時insertがあり、このレコードが他のトランザクションに排他ロックを追加され、排他ロックされたトランザクションがコミットまたはロールバックされると、2つの同時insert操作でデッドロックが発生します.
1.同時挿入の場合、1つのトランザクション内で再トランザクションのコミットは行われません.2.キャッシュ方式などの他の手段により、この同時挿入の問題を解決する.3.シリアル実行に変更します.
参考ドキュメント:Mysqlデッドロックチェックプロセス
同時処理をトランザクションに挿入して管理
トランザクション管理のデータ量はあまり大きくできません.データベースの挿入が同時にデッドロックになります.
デッドロック・テーブルの処理では、データベース・テーブルをバックアップし、インポート・データを再作成できます.
ロック解除
1つ目:show processlist;ロックプロセス、kill idを見つけます.2つ目:mysql>UNLOCK TABLES;
ロックテーブル
バックアップ中にテーブルが更新されないように、データテーブルをロックします.
mysql>LOCK TABLES tbl_name READ;
表に書き込みロックを追加:mysql>LOCK TABLEStbl_name WRITE;
参考-JDBC一括挿入取引バッチ挿入#実戦演習:http://blog.csdn.net/boonya/article/details/70157820#t43