助け合いフォーラム

Oracle DB

Oracle Master Silver SQL 2019(1Z0-071)
問題ID : 26744
問題を開く
次の順番でSQL文を実行した時の説明として、正しいものはどれですか(該当するものを全て選択して下さい)。
なお、それぞれのユーザは、Oracleへの接続には同一アカウント(pingt)を使用して同じデータにアクセスしているものとします。

 ユーザーA:
  SQL> SELECT d.department_name, e.employee_name
   2 FROM departments d JOIN employees e USING (department_id)
   3 FOR UPDATE OF e.employee_name NOWAIT; … ①
 ユーザーB:
  SQL> SELECT employee_id, employee_name FROM employees
   2 FOR UPDATE NOWAIT; … ②
  SQL> SELECT department_id, department_name FROM departments
   2 FOR UPDATE NOWAIT; … ③
 ユーザーA:
  SQL> UPDATE employees SET salary = 350000 WHERE employee_id = 1020;
  SQL> COMMIT;

正解

①を実行すると、EMPLOYEES表の該当する行に排他ロックがかかる

②を実行すると、エラーとなる

③を実行すると、検索結果が表示される

解説

設問のSQL文を1つずつ確認してみましょう。

 ユーザーA:
  SQL> SELECT d.department_name, e.employee_name
   2 FROM departments d JOIN employees e USING (department_id)
   3 FOR UPDATE OF e.employee_name NOWAIT; … ①
 ユーザーB:
  SQL> SELECT employee_id, employee_name FROM employees
   2 FOR UPDATE NOWAIT; … ②
  SQL> SELECT department_id, department_name FROM departments
   2 FOR UPDATE NOWAIT; … ③
 ユーザーA:
  SQL> UPDATE employees SET salary = 350000 WHERE employee_id = 1020;
  SQL> COMMIT;

①:SELECT文のFOR UPDATE句に OF 表名.列名 オプションが指定されています。EMPLOYEES表のEMPLOYEE_NAMEが含まれる行にのみ排他ロックがかけられます。
②:①でユーザーAが排他ロックをかけているため、ユーザーBはSELECT文にFOR UPDATE句を指定しても排他ロックをかけることはできません。さらにNOWAITオプションを指定しているので、SELECT文実行後、直ちにエラーとなります。
③:DEPARTMENTS表には排他ロックはかけられていないので、検索後該当する行が表示されます、

以上より、
・①を実行すると、EMPLOYEES表の該当する行に排他ロックがかかる
・②を実行すると、エラーとなる
・③を実行すると、検索結果が表示される
が正解となります。

設問のSQL文の実行結果は次のようになります。


 
SQLを表示
ユーザーA:
SELECT d.department_name, e.employee_name
FROM departments d JOIN employees e USING (department_id)
FOR UPDATE OF e.employee_name NOWAIT;
ユーザーB:
SELECT employee_id, employee_name FROM employees
FOR UPDATE NOWAIT;

SELECT department_id, department_name FROM departments
FOR UPDATE NOWAIT;
ユーザーA:
UPDATE employees SET salary = 350000 WHERE employee_id = 1020;

SQL> COMMIT;

参考

通常、Oracle DatabaseではSELECT文の実行時はロックをかけませんが、SELECT文にFOR UPDATE句を指定することで、検索対象となる行に排他ロックをかけることができます。
FOR UPDATE句は次のように指定します。

 SELECT 列名 [,列名, ...]
 FROM 表名
 [WHERE 条件]
 FOR UPDATE [OF [表名.]列名] [NOWAIT | WAIT n]
 [ORDER BY 列名 [, 列名, ...]];


 
SQLを表示
ユーザーA:
SELECT employee_id, employee_name, hiredate
FROM employees
WHERE department_id IN (1, 2, 3)
FOR UPDATE;

ユーザーB:
UPDATE employees SET department_id = 5
WHERE hiredate >= '10-04-01';

ユーザーA:
ROLLBACK;


FOR UPDATE句では、次のオプションを指定できます。



[NOWAIT]


 
SQLを表示
ユーザーA:
SELECT employee_id, employee_name, hiredate
FROM employees
FOR UPDATE;

ユーザーB:
SELECT employee_id, employee_name, hiredate
FROM employees
WHERE department_id IN (1, 2, 3)
FOR UPDATE NOWAIT;


[WAIT n]


 
SQLを表示
ユーザーA:
SELECT employee_id, employee_name, hiredate
FROM employees
FOR UPDATE;

ユーザーB:
SELECT employee_id, employee_name, hiredate
FROM employees
FOR UPDATE WAIT 5;


[OF 表名.列名]

FROM句に複数の表が指定されている場合は、それぞれの表の対象となる行にロックをかけますが、


 
SQLを表示
ユーザーA:
SELECT department_name, employee_name, hiredate
FROM departments JOIN employees
USING(department_id)
FOR UPDATE;

ユーザーB:
SELECT department_id, department_name
FROM departments
FOR UPDATE WAIT 3;

SELECT employee_id, employee_name, hiredate
FROM employees
FOR UPDATE WAIT 5;


OF 表名.列名オプションを指定すると、指定した表名.列名を含む行のみにロックを限定できます。


 
SQLを表示
ユーザーA:
SELECT department_name, employee_name, hiredate
FROM departments JOIN employees
USING(department_id)
FOR UPDATE OF departments.department_name;

ユーザーB:
SELECT department_id, department_name
FROM departments
FOR UPDATE WAIT 5;

SELECT employee_id, employee_name, hiredate
FROM employees
FOR UPDATE WAIT 5;
上に戻る

同一アカウントで、異なったユーザでのデータアクセスについて。

退 退会ユーザ
公開日 2024/08/12

本問に以下の記述があります。
「それぞれのユーザは、Oracleへの接続には同一アカウント(pingt)を使用して同じデータにアクセスしているものとします。」

この記述による問題状況の考え方としては、
ユーザA, Bは同一のpingtスキーマの表オブジェクトを同時に接続して参照している
といった認識で合っていますでしょうか。

2024/08/13 10:56

問題ID: 29561 の参考に以下の記述がありました。

※ユーザーを作成すると、同じ名前の「スキーマ」も同時に作成されます。スキーマとは、1人のユーザーが所有するオブジェクトの集合です。

なので、「pingtユーザーでログインしている=pingtスキーマを使用している」と言え、同じ表オブジェクトのデータを参照しているということだと判断できるので、 reo_tokeshi さんのご認識の通りかと思います。


コメント

b beta

2024/08/19 20:17

a

この返信に対して
コメントを記入できます

退 退会ユーザ
2024/08/14 23:46

ご回答ありがとうございました。


コメント

この返信に対して
コメントを記入できます

この投稿に対して返信しませんか?