マルチスレッド処理
Liferay DXP 7.4 U10+ または Liferay Portal 7.4 GA14+
アップグレードプロセス では、大規模なデータセットに対して複雑な変更を行う場合があります。 パフォーマンスがクリティカルな場合は、アプリケーションのUpgradeProcessクラスのprocessConcurrently()メソッドを使用するようにしてください。 このメソッドは複数のスレッドで実行されるため、アップグレードの時間を短縮することができます。
バージョン1.0.0をデプロイする
Liferay DXP の新しいインスタンスを起動するには、以下を実行します。
docker run -it -m 8g -p 8080:8080 liferay/dxp:2026.q1.9-lts
http://localhost:8080 に、メールアドレス test@liferay.com とパスワード test を使用して Liferay にサインインします。 プロンプトが表示されたら、パスワードを learn に変更してください。
次に、以下の手順に従います。
-
マルチスレッド処理 をダウンロードして解凍します。
curl https://resources.learn.liferay.com/examples/liferay-j7z3.zip -Ounzip liferay-j7z3.zip -
1.0.0ディレクトリに移動し、ビルドしてデプロイします。CD 1.0.0../gradlew deploy -Ddeploy.docker.container.id=$(docker ps -lq)注記このコマンドは、デプロイされたjarファイルをDockerコンテナの/opt/liferay/osgi/modulesにコピーするのと同じです。
-
Liferay Dockerコンテナコンソールでデプロイメントを確認してください。
com.acme.j7z3.api_1.0.0 [1030] を開始しました com.acme.j7z3.service_1.0.0 [1031] を開始しました
アプリにエントリーを追加する
-
コントロール パネル → サーバー管理 → スクリプト の順に移動して、スクリプト コンソールを開きます。
-
以下のスクリプトを実行して、エントリを追加してください。
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つのエントリがあります。

アップグレードを実行する
-
1.0.1ディレクトリに移動し、ビルドしてデプロイします。cd ../1.0.1../gradlew deploy -Ddeploy.docker.container.id=$(docker ps -lq) -
コントロール パネル → Gogo シェル で Gogo シェル コンソールに移動します。
-
upgrade:list com.acme.j7z3.serviceと入力して、1.0.1 アップグレードが利用可能であることを確認します。 出力ウィンドウには、バージョン1.0.1が登録済みのアップグレードプロセスとして表示されます。 -
コマンド
upgrade:execute com.acme.j7z3.serviceを入力してアップグレードを実行します。 出力ウィンドウには、アップグレードが完了したことが示されています。
-
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つの部分から成ります。
-
SQLクエリ - データベースデータを照会するためのSQL文。
-
オブジェクトの収集 - 結果セットを受け取り、結果セットに基づいてオブジェクトの配列を返します。
-
オブジェクトの処理 - オブジェクトの配列に対してビジネスロジックを実行します。
-
例外 - 例外が発生した場合にメッセージを送信します。
サンプルプロジェクトでは、 name フィールドが processConcurrently() メソッドによって処理および変更される簡単な例を示しています。
-
select j7z3EntryId, name from J7Z3_J7Z3Entry- SQL ステートメントはすべてのエントリをクエリします。 -
resultSet -> new Object[] { resultSet.getLong("j7z3EntryId"), resultSet.getString("name") }オブジェクトは収集され、
resultSet配列に格納されます。 -
列 -> { 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に設定されます。 -
例外は
nullに設定されます。
processConcurrently() の代替実装
processConcurrently() メソッドには 2 つの代替シグネチャがあります。 最初の方法は、パフォーマンス向上のために自動バッチ処理を使用します。 J7Z3EntryUpgradeProcess.java ファイルで、 processConcurrently() の使用箇所を次のコードに置き換えてください。
processConcurrently(
"select j7z3EntryId, name from J7Z3_J7Z3Entry",
"update J7Z3_J7Z3Entry set name = ? j7z3EntryId = ? の場合"、
resultSet -> new Object[] {
resultSet.getLong("j7z3EntryId"), resultSet.getString("name")
}、
(columns、preparedStatement) -> {
long j7z3EntryId = (Long)columns[0];
preparedStatement.setString(1, "baker");
preparedStatement.setLong(2, j7z3EntryId);
preparedStatement.addBatch();
},
null);
この署名には以下のパラメータがあります。
-
元の実装と同様に、最初の引数は処理対象データを取得するためのSQLクエリです。
-
2番目の引数は、メソッドによって制御されるバッチ内でデータを挿入、更新、または削除するためのSQLクエリです。
-
3番目の引数は、元の実装における関数と同様の関数です。
resultSet -> new Object[] { resultSet.getLong("j7z3EntryId"), resultSet.getString("name") } -
4番目の引数も同様の機能を持っています。
(columns, preparedStatement) -> { long j7z3EntryId = (Long)columns[0]; preparedStatement.setString(1, "baker"); preparedStatement.setLong(2, j7z3EntryId); preparedStatement.addBatch(); } -
最後の引数は、例外が発生した場合に使用される
文字列です。
SQLデータの更新または挿入のみを行うシンプルなアップグレードには、この署名を使用してください。 データの挿入以上の操作(ファイルの削除や画像の追加など)を行うアップグレードには、 以前の署名 を使用してください。
もう一方のシグネチャは、ソースとして配列を渡します。 詳細については、 BaseDBProcess の Javadoc を参照してください。