第266回では、MySQL 9._metadata.の挙動などを検証しましたが、Community EditionではUPDATEやINSERT、DELETEといったDML操作は利用できませんでした。
その後、2026年4月にリリースされたMySQL 9.
そこで今回は、MySQL 9.eTag に注目し、どのようなタイミングで値が変化するのか、また楽観ロックとしてどのように利用できるのかについても確認していきます。
MySQL 9.7でDMLを試してみる
DMLを利用するため、更新対象となるオブジェクトに適切なDMLタグを付与したJSON Duality Viewを作成します。今回は前回と同じテーブル構成を利用し、MySQL 9.WITH(INSERT)やWITH(UPDATE)といったタグを付与する必要があります。authorにWITH(INSERT, UPDATE)、commentsにWITH(INSERT, UPDATE, DELETE)を指定してJSON Duality Viewを作成しました。
mysql> CREATE JSON RELATIONAL DUALITY VIEW post_detail_dv AS
-> SELECT JSON_DUALITY_OBJECT(
-> WITH(INSERT, UPDATE, DELETE)
-> '_id': posts.post_id,
-> 'title': posts.title,
-> 'published_at': posts.published_at,
-> 'author': (
-> SELECT JSON_DUALITY_OBJECT(
-> WITH(INSERT, UPDATE)
-> 'author_id': authors.author_id,
-> 'display_name': authors.display_name
-> )
-> FROM authors
-> WHERE authors.author_id = posts.author_id
-> ),
-> 'comments': (
-> SELECT JSON_ARRAYAGG(
-> JSON_DUALITY_OBJECT(
-> WITH(INSERT, UPDATE, DELETE)
-> 'comment_id': comments.comment_id,
-> 'commenter': comments.commenter,
-> 'body': comments.body,
-> 'created_at': comments.created_at
-> )
-> )
-> FROM comments
-> WHERE comments.post_id = posts.post_id
-> )
-> )
-> FROM posts;
Query OK, 0 rows affected (0.004 sec)
作成したJSON Duality Viewを確認すると、リレーショナルデータを次のようなJSONドキュメントとして参照できます。
mysql> SELECT JSON_PRETTY(data)
-> FROM post_detail_dv
-> WHERE data->>'$._id' = '11';
{
"_id": 11,
"title": "...",
"author": {...},
"comments": [...]
}
それでは、投稿タイトルを更新してみます。実行結果は以下のとおりです。
mysql> UPDATE post_detail_dv
-> SET data = JSON_SET(
-> data,
-> '$.title',
-> 'MySQL 9.7でJSON Duality Viewを再検証してみた'
-> )
-> WHERE data->>'$._id' = '11';
Query OK, 1 row affected (0.004 sec)
Rows affected: 1 Warnings: 0.
更新後にJSON Duality Viewを確認すると、タイトルが変更されていることがわかります。
mysql> SELECT
-> data->>'$._id' AS id,
-> data->>'$._metadata.etag' AS etag,
-> data->>'$.title' AS title
-> FROM post_detail_dv
-> WHERE data->>'$._id' = '11';
+------+----------------------------------+-------------------------------------------------------+
| id | etag | title |
+------+----------------------------------+-------------------------------------------------------+
| 11 | 648d6f9f4418e5af3834ea622e8c6929 | MySQL 9.7でJSON Duality Viewを再検証してみた |
+------+----------------------------------+-------------------------------------------------------+
1 row in set (0.001 sec)
さらにベーステーブル側も確認してみます。
+---------+-------------------------------------------------------+ | post_id | title | +---------+-------------------------------------------------------+ | 11 | MySQL 9.7でJSON Duality Viewを再検証してみた | +---------+-------------------------------------------------------+
JSON Duality View経由で実行した更新は、対応するベーステーブルにも正しく反映されていることが確認できました。このように、MySQL 9.
eTagを観察してみる
前回の記事でも少し触れましたが、JSON Duality Viewには _metadata. というメタデータが含まれています。
JSON Duality Viewを参照すると、以下のようにeTagを確認できます。
mysql> SELECT
-> data->>'$._id' AS id,
-> data->>'$._metadata.etag' AS etag,
-> data->>'$.title' AS title
-> FROM post_detail_dv
-> WHERE data->>'$._id' = '11';
+------+----------------------------------+------------------------------------------------------------+
| id | etag | title |
+------+----------------------------------+------------------------------------------------------------+
| 11 | 683c8b29b965fa95b4b1624d974ad607 | MySQL9.4に追加されたJSON Duality Viewってなに? |
+------+----------------------------------+------------------------------------------------------------+
ドキュメントによると、eTagはドキュメントの状態を表す識別子として利用できます。しかし、どの範囲の変更がeTagの変化として検知されるのかは気になるところです。
そこで今回は、
- JSON Duality View経由の更新
- 同じ値へのUPDATE
- 関連テーブルの更新
を試し、eTagの変化を確認してみましょう。
投稿タイトルを更新してみる
まずはJSON Duality View経由で投稿タイトルを変更します。
UPDATE post_detail_dv SET data = JSON_SET( data, '$.title', 'MySQL 9.7でJSON Duality Viewを再検証してみた' ) WHERE data->>'$._id' = '11';
更新後のeTagは以下のようになりました。
+------+----------------------------------+-------------------------------------------------------+ | id | etag | title | +------+----------------------------------+-------------------------------------------------------+ | 11 | 648d6f9f4418e5af3834ea622e8c6929 | MySQL 9.7でJSON Duality Viewを再検証してみた | +------+----------------------------------+-------------------------------------------------------+
更新前と比較すると、eTagが変化していることがわかります。
同じ値でUPDATEしてみる
続いて、同じ値でUPDATEを実行します。
UPDATE post_detail_dv SET data = JSON_SET( data, '$.title', 'MySQL 9.7でJSON Duality Viewを再検証してみた' ) WHERE data->>'$._id' = '11';
再度eTagを確認すると、値は変化していません。
+------+----------------------------------+-------------------------------------------------------+ | id | etag | title | +------+----------------------------------+-------------------------------------------------------+ | 11 | 648d6f9f4418e5af3834ea622e8c6929 | MySQL 9.7でJSON Duality Viewを再検証してみた | +------+----------------------------------+-------------------------------------------------------+
少なくとも今回の検証では、eTagはUPDATE文の実行有無ではなく、実際にドキュメントの内容が変化したかどうかを基準に更新されているようです。
関連テーブルを更新してみる
次に、JSON Duality Viewを経由せず、ベーステーブル側を直接更新してみます。
まずは投稿者名を変更します。
UPDATE authors SET display_name = 'Fukamachi_v97' WHERE author_id = 1;
更新後に再度JSON Duality Viewを確認すると、投稿者名だけでなくeTagも変化していました。
+------+----------------------------------+---------------+ | id | etag | author_name | +------+----------------------------------+---------------+ | 11 | 082555f119b4087a59fb80e57e07a0d2 | Fukamachi_v97 | +------+----------------------------------+---------------+
続いてコメント本文も変更してみます。
UPDATE comments SET body = 'CommunityでもDMLできるようになったか知りたい' WHERE comment_id = 100;
結果は以下のとおりです。
+------+----------------------------------+--------------------------------------------------------------+ | id | etag | first_comment | +------+----------------------------------+--------------------------------------------------------------+ | 11 | 1d95b60370e02be3641631d09237525d | CommunityでもDMLできるようになったか知りたい | +------+----------------------------------+--------------------------------------------------------------+
コメント本文の変更でもeTagが変化していることが確認できました。
今回の結果をまとめると、以下のようになります。
| 操作 | eTag変化 |
|---|---|
| JSON Duality View経由でtitle更新 | ○ |
| 同値UPDATE | × |
| authors. |
○ |
| comments. |
○ |
期待どおり、JSON Duality View経由でドキュメントを更新した場合はeTagが変化しました。一方で、同じ値へのUPDATEでは変化せず、関連テーブルを直接更新した場合でもeTagが変化していることがわかります。
今回の検証結果を見る限り、eTagは`posts`テーブルだけでなく、ネストされた`author`や`comments`を含めたドキュメント全体の状態を表しているようです。また、UPDATE文の実行有無ではなく、実際にドキュメント内容が変化した場合にのみeTagが更新されることも確認できました。
eTagを利用した楽観ロック
前節の検証から、eTagはJSON Duality Viewが表現するドキュメント全体の状態を表していることがわかりました。
続いて、このeTagを利用した更新競合の検知を試してみます。
mysql> SELECT
-> data->>'$._metadata.etag' AS etag
-> FROM post_detail_dv
-> WHERE data->>'$._id' = '11';
+----------------------------------+
| etag |
+----------------------------------+
| 1d95b60370e02be3641631d09237525d |
+----------------------------------+
ここで、過去のeTagを利用して更新を試してみます。今回は、投稿者情報を更新する前のeTagである082555f119b4087a59fb80e57e07a0d2を指定してみます。
mysql> UPDATE post_detail_dv
-> SET data = JSON_SET(
-> data,
-> '$.title',
-> '古いeTagで更新してみる',
-> '$._metadata.etag',
-> '082555f119b4087a59fb80e57e07a0d2'
-> )
-> WHERE data->>'$._id' = '11';
ERROR 6494 (HY000): Cannot update JSON duality view. The ETAG of the document in the database did not match the ETAG '"082555f119b4087a59fb80e57e07a0d2"' passed in.
更新は失敗しました。
続いて、現在のeTagを利用して同じ更新を試してみます。
mysql> UPDATE post_detail_dv
-> SET data = JSON_SET(
-> data,
-> '$.title',
-> 'eTagを指定して更新してみる',
-> '$._metadata.etag',
-> '1d95b60370e02be3641631d09237525d'
-> )
-> WHERE data->>'$._id' = '11';
Query OK, 1 row affected (0.003 sec)
更新後の状態を確認すると、タイトルが変更されていることがわかります。
+------+----------------------------------+---------------------------------------+ | id | etag | title | +------+----------------------------------+---------------------------------------+ | 11 | 22eb0d3b95bc472443515ee24354a13b | eTagを指定して更新してみる | +------+----------------------------------+---------------------------------------+
更新後にはeTagも新しい値へ変化しています。このように、JSON Duality ViewではeTagを利用した楽観ロックを実現できます。
一般的なversionカラムによる楽観ロックでは、関連テーブルの変更を検知するためには追加の実装が必要になります。一方、今回の検証結果を見る限り、JSON Duality ViewのeTagはドキュメント全体の状態を基に生成されているため、authorやcommentsを含めた変更も検知できるようです。
JSON Duality Viewを利用する場合、eTagは単なるメタデータではなく、更新競合を検知するための重要な仕組みとして利用できそうです。
まとめ
今回はMySQL 9.
また、eTagの挙動についても改めて確認してみました。今回の検証では、ルートオブジェクトである posts の変更だけでなく、ネストされた author や comments の変更でもeTagが変化することがわかりました。一方で、同じ値へのUPDATEではeTagは変化せず、JSON Duality Viewが表現するドキュメント全体の状態を基に生成されているようです。
特に興味深かったのは、eTagを利用した楽観ロックです。一般的なversionカラムによる実装では関連テーブルの変更を検知するために追加の実装が必要になりますが、今回の検証結果を見る限り、JSON Duality ViewではeTagによってそれらの変更も検知できる可能性があります。
前回の記事を書いた時点では、JSON Duality Viewは
本稿で紹介した内容以外にも、DMLタグの詳細や更新可能なオブジェクトに関する制約などが存在します。興味のある方は公式ドキュメントも参照してみてください。