Documentation

マルチスレッド処理

Liferay DXP 7.4 U10以降およびLiferay Portal7.4 GA14以降で利用可能

アップグレードプロセスでは、大規模なデータセットに複雑な変更を加える必要がある場合があります。 パフォーマンスがクリティカルな場合は、アプリケーションのUpgradeProcessクラスのprocessConcurrently()メソッドを使用するようにしてください。 このメソッドは複数のスレッドで実行されるため、アップグレードの時間を短縮することができます。

バージョン1.0.0をデプロイする

新しいLiferay DXPインスタンスを起動し、以下を実行します。

docker run -it -m 8g -p 8080:8080 liferay/dxp:7.4.13-u29。

メールアドレス_test@liferay.com_とパスワード_test_を使用して、http://localhost:8080でLiferayにサインインしてください。 プロンプトが表示されたら、パスワードを _learn_に変更します。

次に、以下の手順に従います。

  1. マルチスレッド処理 をダウンロードし、解凍してください。

    curl https://learn.liferay.com/dxp/latest/en/building-applications/data-frameworks/upgrade-processes/liferay-j7z3.zip -O
    
    unzip liferay-j7z3.zip
    
  2. 1.0.0ディレクトリに移動し、ビルドとデプロイを行います。

    cd 1.0.0
    
    ../gradlew deploy -Ddeploy.docker.container.id=$(docker ps -lq)
    

    注釈

    このコマンドは、デプロイされたjarをDockerコンテナの/opt/liferay/osgi/modulesにコピーするのと同じです。

  3. Liferay Dockerコンテナコンソールでデプロイを確認します。

    STARTED com.acme.j7z3.api_1.0.0 [1030]
    STARTED com.acme.j7z3.service_1.0.0 [1031]
    

アプリにエントリーを追加する

  1. コントロールパネル] → [サーバ管理] → [スクリプト] でスクリプトコンソールに移動します。

  2. 以下のスクリプトを実行して、いくつかのエントリーを追加してください。

    import com.acme.j7z3.service.J7Z3EntryLocalServiceUtil;
    
    import com.liferay.portal.kernel.dao.orm.QueryUtil;
    
    entry1 = J7Z3EntryLocalServiceUtil.createJ7Z3Entry(1);
    entry2 = J7Z3EntryLocalServiceUtil.createJ7Z3Entry(2);
    entry3 = J7Z3EntryLocalServiceUtil.createJ7Z3Entry(3);
    
    entry1.setName("able");
    entry2.setName("able");
    entry3.setName("able");
    
    J7Z3EntryLocalServiceUtil.addJ7Z3Entry(entry1);
    J7Z3EntryLocalServiceUtil.addJ7Z3Entry(entry2);
    J7Z3EntryLocalServiceUtil.addJ7Z3Entry(entry3);
    

    J7Z3_J7Z3Entryテーブルには、3つのエントリーが追加されました。

    この3つのエントリーは、データベースのテーブルで確認することができます。

アップグレードの実行

  1. 1.0.1ディレクトリに移動し、ビルドとデプロイを行います。

    cd ../1.0.1    
    
    ../gradlew deploy -Ddeploy.docker.container.id=$(docker ps -lq)
    
  2. コントロールパネル] → [Gogo シェル] でGogoシェルコンソールに移動します。

  3. upgrade:list com.acme.j7z3.serviceというコマンドを入力し、1.0.1へのアップグレードが可能であることを確認します。 1.0.1バージョンは、出力ウィンドウに登録されたアップグレードプロセスとして表示されます。

  4. upgrade:execute com.acme.j7z3.serviceというコマンドを入力して、アップグレードを実行します。 [出力]ウィンドウには、アップグレードが完了したことが表示されます。

    アップグレードを実行すると、アップグレードが完了したことが出力されます。

  5. J7Z3_J7Z3Entryテーブルのエントリーが更新されました。

    更新されたエントリーは、データベースのテーブルで確認することができます。

マルチスレッドメソッドの実装

アプリケーションのUpgradeProcessクラスで、processConcurrently()メソッドをオーバーライドしてください。

@Override
protected void doUpgrade() throws Exception {
	processConcurrently(
		"select j7z3EntryId, name from J7Z3_J7Z3Entry",
		resultSet -> new Object[] {
			resultSet.getLong("j7z3EntryId"), resultSet.getString("name")
		},
		columns -> {
			long j7z3EntryId = (Long)columns[0];

			try (PreparedStatement preparedStatement =
					connection.prepareStatement(
						"update J7Z3_J7Z3Entry set name = ? where " +
							"j7z3EntryId = ?")) {

				preparedStatement.setString(1, "baker");
				preparedStatement.setLong(2, j7z3EntryId);

				preparedStatement.executeUpdate();
			}
		},
		null);
}

メソッドは4つのパートで構成されています。

  1. SQLクエリ - データベースのデータを照会するためのSQL文。

  2. オブジェクトを収集する - 結果セットを受け取り、結果セットに基づいたオブジェクトの配列を返します。

  3. オブジェクトの処理 - オブジェクトの配列に対してビジネスロジックを実行します。

  4. 例外 - 例外が発生した場合、メッセージを送信します。

サンプルプロジェクトでは、 nameフィールドを processConcurrently()メソッドで処理・変更する簡単な例を示しました。

  1. select j7z3EntryId, name from J7Z3_J7Z3Entry - SQL文はすべてのエントリーを照会します。

  2. 
    

    オブジェクトは収集され、resultSet配列に格納されます。

  3. columns -> {
     long j7z3EntryId = (Long)columns[0];
    
     try (PreparedStatement preparedStatement =
             connection.prepareStatement(
                 "update J7Z3_J7Z3Entry set name = ? where " +
                     "j7z3EntryId = ?")) {
    
             preparedStatement.setString(1, "baker");
             preparedStatement.setLong(2, j7z3EntryId);
    
             preparedStatement.executeUpdate();
             }
         }
    

    j7z3EntryIdごとに、nameフィールドをbakerに設定しています。

  4. 例外は、 nullに設定されます。

processConcurrently()メソッドは2つの異なるシグネチャを持っていることに注意しましょう。 このチュートリアルの例に見られるように、1つのシグネチャはSQLクエリをソースとして渡します。 もう一つのシグネチャはソースとして配列を渡します。 詳細は、BaseDBProcess javadocsを参照してください。