演習: ロックについて
重要
この演習を完了するには、自分の Azure サブスクリプションが必要です。 Azure サブスクリプションを持っていない場合は、Azure の無料試用版を作成してください。
この演習を完了するには、以下の準備が整っている必要があります。
- リソース グループを作成済み (モジュール 1 のユニット 5 を参照)。
- Azure Database for MySQL フレキシブル サーバーを作成済み (モジュール 1 のユニット 5 を参照)
- MySQL Workbench をダウンロードおよびインストール済み (モジュール 2 のユニット 5 を参照)。
- Zoo データベースを作成済み (モジュール 2 のユニット 5 を参照)。
- この演習のスクリプトを GitHub からダウンロード済み。
ヒント
最後のラボの完了後に Azure Database for MySQL サーバーを停止した場合は、ここで再起動します。
準備 - MySQL Workbench を構成する
MySQL Workbench を開き、上部のメニューから [編集]>[Preferences] (設定) を選択します。
左側のナビゲーションの [General Editors] (汎用エディター) で、[その他] を選択します。
[その他] で、[Allow more than one instance of MySQL Workbench to run] (MySQL Workbench の複数のインスタンスの実行を許可する) をオンにします。
左側のナビゲーションから、[SQL エディター] を選択します。
[MySQL セッション] で、[DBMS connection read timeout interval (in seconds):] (DBMS 接続の読み取りタイムアウト間隔 (秒単位)) を 300 に変更します (既定値は 30 秒です)
[OK] を選択し、MySQL Workbench を閉じます。
MySQL Workbench を開いて、Azure Database for MySQL フレキシブル サーバーに接続します。
[ファイル]、[SQL スクリプトを開く] の順に選択し、Lab5_repopulateAnimals.sql を選択します。
[クエリ]>[実行 (すべてまたは選択)] を選択します。 これにより、ストアド プロシージャ RepopulateAnimals が作成されます。
トランザクションを理解する
- MySQL Workbench で、[ファイル]、[SQL スクリプトを開く] の順に選択し、Lab5_transactions.sql を選択します。
- 最初のセクションを強調表示し、実行します - Use the ZooDb database (ZooDb データベースを使用する)。 これにより、ZooDb が現在のデータベースになり、正しいデータベースを使用していることが確認されます。
- 次のセクションを強調表示し、実行します - Repopulate animal table (animal テーブルを再作成する)。 これにより、クリーンなデータで操作を開始できるようになります。
- 次のセクションを強調表示し、実行します - Query autocommit (autocommit を照会する)。 これにより、1 が返されます。これは、autocommit が ON であることを示します。
- 次のセクションを強調表示し、実行します - When autocommit is on each SQL statement is a transaction (自動コミットがオンの場合、各 SQL ステートメントはトランザクションである)。
- セクション Name has been changed to Vampire bat #1 (名前が Vampire bat #1 に変更されている) を強調表示し、実行します。 これにより、前の
UPDATE
ステートメントがコミットされたことが示されます。 - 次のセクションを強調表示し、実行します - Explicit transaction (明示的なトランザクション)。 明示的なトランザクションが
START TRANSACTION
で開始され、COMMIT
で終了します。SELECT
ステートメントによって名前の変更が返されました。これは変更がコミットされたことを示しています。 - 次のセクションを強調表示し、実行します - A transaction is Atomic (トランザクションはアトミックである)。
SELECT
ステートメントによって、追加の行を含む結果セットが返されました。 ステートメントがアトミックであるため、ステートメント内のすべての列が含まれています。アトミックとは、すべてがコミットされるか、何もコミットされないということです。 - 次のセクションを強調表示し、実行します - Rollback the transaction (トランザクションをロールバックする)。
- MySQL Workbench を開いたままにして、次の演習の準備をします。
ロックについて
注意
この演習では、2 人のユーザーをシミュレートするために、MySQL Workbench のインスタンスを 2 つ開く必要があります。 「準備 - MySQL Workbench を構成する」の手順を完了していることを確認してください。
- MySQL Workbench の開いているインスタンスで、[ファイル]>[SQL スクリプトを開く] を選択し、Lab5_basic_locking.sql に移動して [開く] を選択します。
- MySQL Workbench の 2 つ目のインスタンスを開きます。 [データベース]、[データベースに接続] の順に選択し、[Stored Connection] (保存された接続) を選択して Azure Database for MySQL フレキシブル サーバーに接続します。
- [ファイル]>[SQL スクリプトを開く] を選択し、Lab5_basic_locking.sql に移動して [開く] を選択します。 これで、MySQL Workbench の 2 つのインスタンスが開き、それぞれで Lab5_basic_locking.sql を開いた状態になります。 MySQL Workbench の 1 つ目のインスタンスをインスタンス A と呼び、MySQL Workbench の 2 つ目のインスタンスをインスタンス B と呼びます。
- インスタンス A で、1. Run this in Instance A (1. インスタンス A でこれを実行する) とマークされたセクションを強調表示し、実行します。これにより、トランザクションが開始され、AnimalID = 14 の名前が "Percy Penguin" に設定されます。
- インスタンス B で、2. Run this in Instance B (インスタンス B でこれを実行する) とマークされたセクションを強調表示し、実行します。SELECT ステートメントによって AnimalID = 14 が返されますが、名前は変更されていません。 これは、インスタンス A のトランザクションがコミットされなかったためです。 インスタンス B が名前を更新しようとすると、インスタンス A が保持しているロックによって、それが防止されます。
- インスタンス A で、3. Run this in Instance A (3. インスタンス A でこれを実行する) とマークされたセクションを強調表示し、実行します。これにより、2 つのトランザクションが表示されます。 インスタンス B のトランザクションは、インスタンス A のトランザクションが完了するのを待機しています。 インスタンス A がトランザクションをコミットすると、インスタンス B が操作を完了できるようになるので、開いているトランザクションはなくなります。 インスタンス B によって行われた変更も確認できます。名前が "Percival Penguin" に更新されています。次の演習のために、MySQL Workbench のインスタンスは両方とも開いたままにしておいてください。
分離レベルについて理解する
- インスタンス A で、10. Run this in Instance A (10. インスタンス A でこれを実行する) とマークされたセクションを強調表示し、実行します。これによりトランザクションが開始されますが、操作は完了しません。
- インスタンス B で、11. Run this in Instance B (11. インスタンス B でこれを実行する) とマークされたセクションを強調表示し、実行します。
- インスタンス A で、12. Run this in Instance A (12. インスタンス A でこれを実行する) とマークされたセクションを強調表示し、実行します。これは、手順 1 で開始したのと同じトランザクション内にとどまります。
注意
さまざまな分離レベルでこの演習を試してください。
デッドロックについて理解する
- MySQL Workbench を開いて、Azure Database for MySQL フレキシブル サーバーに接続します。 MySQL Workbench のこのインスタンスを、インスタンス A と呼びます。
- MySQL Workbench の 2 つ目のインスタンスを開いて、Azure Database for MySQL フレキシブル サーバーに接続します。 MySQL Workbench のこのインスタンスを、インスタンス B と呼びます。
- インスタンス A で、次のセクションを強調表示し、実行します - Use ZooDb and avoid locks timing out (ZooDb を使用し、ロックのタイムアウトを回避する)。
- インスタンス B で、次のセクションを強調表示し、実行します - Use ZooDb and avoid locks timing out (ZooDb を使用し、ロックのタイムアウトを回避する)。
- インスタンス A で、次のセクションを強調表示し、実行します - Repopulate Animal table, and start a transaction (Animal テーブルを再作成し、トランザクションを開始する)。 これによりトランザクションが開始されますが、
COMMIT
でもROLLBACK
でも完了しません。 - インスタンス B で、次のセクションを強調表示し、実行します - Two updates in the reverse order to Instance A (インスタンス A に対する 2 つの逆順の更新)。
- インスタンス A で、次のセクションを強調表示し、実行します - The server rolls back one of the two transactions (サーバーによって 2 つのトランザクションのいずれかがロールバックされる)。 サーバーによってデッドロックが自動的に認識され、2 つのトランザクションのいずれか 1 つがロールバックされます。 SELECT ステートメントでは、コミットされたトランザクションだけが返されます。