1

スキーマが異なる別のデータベースに 2 つのテーブルがあるプロジェクトに取り組み始めました。そのため、データベースに接続するために 2 つの異なる接続パラメーターを使用します。各データベースに接続した後、対応するテーブルで指定された sql を使用して、これら 2 つのテーブルに挿入する必要があります。

そして、コマンド ライン パラメータに応じて、JDBC を使用して 2 つのテーブルすべてまたはいずれか 1 つに挿入することになっています。つまり、1 つのスレッドが Table1 と Table2、またはそれらのいずれかに挿入されます。

コマンド ライン パラメータ:- ここで、10 はスレッド数、100 はタスク数、table1 と table2 はテーブル名です。

10 100 table1 table2

以下は私のコードです。このコードでは、 という名前のテーブルを 1 つだけ渡すとtable1、table1 用の SQL を使用してそのテーブルに挿入されます。

またid、両方に同じものを挿入する必要がtable1ありtable2、それはConstructoridとして渡されます。つまり、 ifの場合、これはとの両方にあるはずです。AtomicIntegerTaskid is 11 idtable1table2

 final AtomicInteger id = new AtomicInteger(1);

 ExecutorService service = Executors. newFixedThreadPool(noOfThreads);

 for (int i = 0; i < noOfTasks * noOfThreads; i++) {

      for (String arg : tableNames) {
          String url = (String) prop.get(arg + ".url");
          String user = (String) prop.get(arg + ".user");
          String password = (String) prop.get(arg + ".password");
          String driver = (String) prop.get(arg + ".driver");
          String suffix = (String) prop.get(arg + ".suffix");
          String sql = (String) prop.get(arg + ".sql");

          service.submit( new Task(id, url, user, password, driver, sql, suffix));
        }
    }

以下は、Runnable インターフェイスを実装する Task クラスです。

class Task implements Runnable {

    private final AtomicInteger id ;
    private final String url ;
    private final String username ;
    private final String password ;
    private final String sql ;
    private final String driver ;
    private final String suffix ;

    public Task(AtomicInteger id, String url, String user, String password, String driver, String sql, String suffix) {
        this.id = id;
        this.url = url;
        this.username = user;
        this.password = password;
        this.driver = driver;
        this.sql = sql;
        this.suffix = suffix;
    }

    @Override
    public void run() {

        try {

           dbConnection = getDBConnection(url , username , password , driver );
           callableStatement = dbConnection .prepareCall(sql);

           int userId = id .getAndIncrement();

           callableStatement.setString(1, String.valueOf(userId));

        //other callableStatement


        callableStatement.executeUpdate();
       }
    }

したがって、上記のプログラムを Number of Threads as10や Number of Tasks as1000などの複数のスレッドで実行し、 asidを選択した場合1

次に、両方のテーブルに同じ ID はありませんtable1。つまり、ID 1 はどちらか一方のテーブルにのみ存在しますtable2。私が考えることができる唯一の理由idは、毎回スレッドごとAtomicIntegerに新しいものを取得することです。id同じ ID を使用して各テーブルに挿入する方法はありますか? そしてPrimaryKey、それらのテーブルに再度挿入する場合、各スレッドが新しい ID を取得するように id を確認します。

4

1 に答える 1

0

私があなたを正しく理解していれば、重複を避けるためにカウンターを静的として定義する必要がありますPrimaryKey

static AtomicInteger id;

次に、次のようにインクリメント コードをメイン ループに移動します (クラスint userId = id .getAndIncrement();内のを削除することを忘れないでください)。Task

for (int i = 0; i < noOfTasks * noOfThreads; i++) {
  // add following line
  int userId = id.getAndIncrement();

  for (String arg : tableNames) {
      String url = (String) prop.get(arg + ".url");
      String user = (String) prop.get(arg + ".user");
      String password = (String) prop.get(arg + ".password");
      String driver = (String) prop.get(arg + ".driver");
      String suffix = (String) prop.get(arg + ".suffix");
      String sql = (String) prop.get(arg + ".sql");

      service.submit( new Task(id, url, user, password, driver, sql, suffix));
    }
}

さらに、idカウンターはメモリに保持されるため、永続化する必要がある場合があります。そうしないと、アプリケーションの再起動後に 0 にリセットされます。

于 2013-02-18T07:12:56.690 に答える