マルチスレッド処理
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-u55。
メールアドレス[email protected]_とパスワード_test_を使用して、http://localhost:8080でLiferayにサインインしてください。 プロンプトが表示されたら、パスワードを _learn_に変更します。
次に、以下の手順に従います。
マルチスレッド処理 をダウンロードし、解凍してください。
curl https://resources.learn.liferay.com/dxp/latest/ja/building-applications/data-frameworks/upgrade-processes/liferay-j7z3.zip -O
unzip liferay-j7z3.zip
1.0.0
ディレクトリに移動し、ビルドとデプロイを行います。cd 1.0.0
../gradlew deploy -Ddeploy.docker.container.id=$(docker ps -lq)
noteこのコマンドは、デプロイされたjarをDockerコンテナの/opt/liferay/osgi/modulesにコピーするのと同じです。
Liferay Dockerコンテナコンソールでデプロイを確認します。
STARTED com.acme.j7z3.api_1.0.0 [1030] STARTED 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
配列に格納されます。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
に設定しています。例外は、
null
に設定されます。
processConcurrently()
メソッドは2つの異なるシグネチャを持っていることに注意しましょう。 このチュートリアルの例に見られるように、1つのシグネチャはSQLクエリをソースとして渡します。 もう一つのシグネチャはソースとして配列を渡します。 詳細は、 BaseDBProcess javadocs を参照してください。