演習: ロックについて

完了

重要

この演習を完了するには、自分の 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 を構成する

  1. MySQL Workbench を開き、上部のメニューから [編集]>[Preferences] (設定) を選択します。

  2. 左側のナビゲーションの [General Editors] (汎用エディター) で、[その他] を選択します。

  3. [その他] で、[Allow more than one instance of MySQL Workbench to run] (MySQL Workbench の複数のインスタンスの実行を許可する) をオンにします。

    [Workbench の基本設定] の [その他の設定] ページを示すスクリーンショット。

  4. 左側のナビゲーションから、[SQL エディター] を選択します。

  5. [MySQL セッション] で、[DBMS connection read timeout interval (in seconds):] (DBMS 接続の読み取りタイムアウト間隔 (秒単位)) を 300 に変更します (既定値は 30 秒です)

    [Workbench の基本設定] の [SQL エディターの設定] ページを示すスクリーンショット。

  6. [OK] を選択し、MySQL Workbench を閉じます。

  7. MySQL Workbench を開いて、Azure Database for MySQL フレキシブル サーバーに接続します。

  8. [ファイル][SQL スクリプトを開く] の順に選択し、Lab5_repopulateAnimals.sql を選択します。

  9. [クエリ]>[実行 (すべてまたは選択)] を選択します。 これにより、ストアド プロシージャ RepopulateAnimals が作成されます。

トランザクションを理解する

  1. MySQL Workbench で、[ファイル][SQL スクリプトを開く] の順に選択し、Lab5_transactions.sql を選択します。
  2. 最初のセクションを強調表示し、実行します - Use the ZooDb database (ZooDb データベースを使用する)。 これにより、ZooDb が現在のデータベースになり、正しいデータベースを使用していることが確認されます。
  3. 次のセクションを強調表示し、実行します - Repopulate animal table (animal テーブルを再作成する)。 これにより、クリーンなデータで操作を開始できるようになります。
  4. 次のセクションを強調表示し、実行します - Query autocommit (autocommit を照会する)。 これにより、1 が返されます。これは、autocommit が ON であることを示します。
  5. 次のセクションを強調表示し、実行します - When autocommit is on each SQL statement is a transaction (自動コミットがオンの場合、各 SQL ステートメントはトランザクションである)
  6. セクション Name has been changed to Vampire bat #1 (名前が Vampire bat #1 に変更されている) を強調表示し、実行します。 これにより、前の UPDATE ステートメントがコミットされたことが示されます。
  7. 次のセクションを強調表示し、実行します - Explicit transaction (明示的なトランザクション)。 明示的なトランザクションが START TRANSACTION で開始され、COMMIT で終了します。SELECT ステートメントによって名前の変更が返されました。これは変更がコミットされたことを示しています。
  8. 次のセクションを強調表示し、実行します - A transaction is Atomic (トランザクションはアトミックである)SELECT ステートメントによって、追加の行を含む結果セットが返されました。 ステートメントがアトミックであるため、ステートメント内のすべての列が含まれています。アトミックとは、すべてがコミットされるか、何もコミットされないということです。
  9. 次のセクションを強調表示し、実行します - Rollback the transaction (トランザクションをロールバックする)
  10. MySQL Workbench を開いたままにして、次の演習の準備をします。

ロックについて

注意

この演習では、2 人のユーザーをシミュレートするために、MySQL Workbench のインスタンスを 2 つ開く必要があります。 「準備 - MySQL Workbench を構成する」の手順を完了していることを確認してください。

  1. MySQL Workbench の開いているインスタンスで、[ファイル]>[SQL スクリプトを開く] を選択し、Lab5_basic_locking.sql に移動して [開く] を選択します。
  2. MySQL Workbench の 2 つ目のインスタンスを開きます。 [データベース][データベースに接続] の順に選択し、[Stored Connection] (保存された接続) を選択して Azure Database for MySQL フレキシブル サーバーに接続します。
  3. [ファイル]>[SQL スクリプトを開く] を選択し、Lab5_basic_locking.sql に移動して [開く] を選択します。 これで、MySQL Workbench の 2 つのインスタンスが開き、それぞれで Lab5_basic_locking.sql を開いた状態になります。 MySQL Workbench の 1 つ目のインスタンスをインスタンス A と呼び、MySQL Workbench の 2 つ目のインスタンスをインスタンス B と呼びます。
  4. インスタンス A で、1. Run this in Instance A (1. インスタンス A でこれを実行する) とマークされたセクションを強調表示し、実行します。これにより、トランザクションが開始され、AnimalID = 14 の名前が "Percy Penguin" に設定されます。
  5. インスタンス B で、2. Run this in Instance B (インスタンス B でこれを実行する) とマークされたセクションを強調表示し、実行します。SELECT ステートメントによって AnimalID = 14 が返されますが、名前は変更されていません。 これは、インスタンス A のトランザクションがコミットされなかったためです。 インスタンス B が名前を更新しようとすると、インスタンス A が保持しているロックによって、それが防止されます。
  6. インスタンス A で、3. Run this in Instance A (3. インスタンス A でこれを実行する) とマークされたセクションを強調表示し、実行します。これにより、2 つのトランザクションが表示されます。 インスタンス B のトランザクションは、インスタンス A のトランザクションが完了するのを待機しています。 インスタンス A がトランザクションをコミットすると、インスタンス B が操作を完了できるようになるので、開いているトランザクションはなくなります。 インスタンス B によって行われた変更も確認できます。名前が "Percival Penguin" に更新されています。次の演習のために、MySQL Workbench のインスタンスは両方とも開いたままにしておいてください。

分離レベルについて理解する

  1. インスタンス A で、10. Run this in Instance A (10. インスタンス A でこれを実行する) とマークされたセクションを強調表示し、実行します。これによりトランザクションが開始されますが、操作は完了しません。
  2. インスタンス B で、11. Run this in Instance B (11. インスタンス B でこれを実行する) とマークされたセクションを強調表示し、実行します。
  3. インスタンス A で、12. Run this in Instance A (12. インスタンス A でこれを実行する) とマークされたセクションを強調表示し、実行します。これは、手順 1 で開始したのと同じトランザクション内にとどまります。

注意

さまざまな分離レベルでこの演習を試してください。

デッドロックについて理解する

  1. MySQL Workbench を開いて、Azure Database for MySQL フレキシブル サーバーに接続します。 MySQL Workbench のこのインスタンスを、インスタンス A と呼びます。
  2. MySQL Workbench の 2 つ目のインスタンスを開いて、Azure Database for MySQL フレキシブル サーバーに接続します。 MySQL Workbench のこのインスタンスを、インスタンス B と呼びます。
  3. インスタンス A で、次のセクションを強調表示し、実行します - Use ZooDb and avoid locks timing out (ZooDb を使用し、ロックのタイムアウトを回避する)
  4. インスタンス B で、次のセクションを強調表示し、実行します - Use ZooDb and avoid locks timing out (ZooDb を使用し、ロックのタイムアウトを回避する)
  5. インスタンス A で、次のセクションを強調表示し、実行します - Repopulate Animal table, and start a transaction (Animal テーブルを再作成し、トランザクションを開始する)。 これによりトランザクションが開始されますが、COMMIT でも ROLLBACK でも完了しません。
  6. インスタンス B で、次のセクションを強調表示し、実行します - Two updates in the reverse order to Instance A (インスタンス A に対する 2 つの逆順の更新)
  7. インスタンス A で、次のセクションを強調表示し、実行します - The server rolls back one of the two transactions (サーバーによって 2 つのトランザクションのいずれかがロールバックされる)。 サーバーによってデッドロックが自動的に認識され、2 つのトランザクションのいずれか 1 つがロールバックされます。 SELECT ステートメントでは、コミットされたトランザクションだけが返されます。