質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
排他制御

排他制御とは、特定のファイル・データへのアクセスや更新を制御することです。特にファイルやデータベースへ書き込みを行う際、データの整合性を保つため別のプログラムによる書き込みを一時的に制御することを指します。

UIテスト

UIテストは、エンドツーエンドのテストのことで、人間がチェックする際と同じ内容をテストが自動で行います。UIの操作はもちろん、サーバーへのレスポンスやリクエスト、サーバーでのロジック処理など、全レイヤーを通してテストすることが可能。汎用性が高い点も特長です。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

トランザクション

トランザクションとは、関連・依存する処理を一連の不可分な処理単位として扱う処理方式を指します。トランザクションとして管理された処理は「すべて成功」か「すべて失敗」のいずれかであることが保証される。処理に失敗した場合は、一連の処理がロールバックされます。

FuelPHP

FuelPHPは、軽量高速で開発が可能なPHPのWebアプリケーションフレームワークです。

Q&A

解決済

1回答

979閲覧

トランザクション処理を確認する為の同時実行テストの方法

kutou

総合スコア9

排他制御

排他制御とは、特定のファイル・データへのアクセスや更新を制御することです。特にファイルやデータベースへ書き込みを行う際、データの整合性を保つため別のプログラムによる書き込みを一時的に制御することを指します。

UIテスト

UIテストは、エンドツーエンドのテストのことで、人間がチェックする際と同じ内容をテストが自動で行います。UIの操作はもちろん、サーバーへのレスポンスやリクエスト、サーバーでのロジック処理など、全レイヤーを通してテストすることが可能。汎用性が高い点も特長です。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

トランザクション

トランザクションとは、関連・依存する処理を一連の不可分な処理単位として扱う処理方式を指します。トランザクションとして管理された処理は「すべて成功」か「すべて失敗」のいずれかであることが保証される。処理に失敗した場合は、一連の処理がロールバックされます。

FuelPHP

FuelPHPは、軽量高速で開発が可能なPHPのWebアプリケーションフレームワークです。

0グッド

0クリップ

投稿2023/08/29 01:43

実現したいこと

  • 登録処理のトランザクションが正しく動作していることを確認するテスト方法が知りたい

※ツールでもコードでもどちらでも良いです

前提

FuelPHPで書かれたWebサイトの登録機能を改修しております。
既存仕様では受付番号の採番処理を行う際、登録済みの受付番号の最大値を取得して、+1した値を受付番号として新規登録するという作りになっていました。
この処理に排他制御がなく、同時に複数の登録があった場合に重複した受付番号を登録してしまう不具合が存在しています。
不具合解消の為、受付番号の最大値取得処理~新規登録までをトランザクションで囲う対応を行います。

この改修について、修正前の不具合の再現と、修正後の不具合の解消をテストで確認する必要があります。

発生している問題・エラーメッセージ

トランザクションが正しく機能していることを確認するテストの実行方法がわかりません。

試したこと

必要なのは同時に複数の登録処理が走ることなので、Postman(PostmanEchoというリクエストを複数回走らせる機能があったので)などのサービスを検討しましたが、レスポンスを待たないで同時にリクエストを実行する、という機能ではなく今回の目的にあっていませんでした。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yambejp

2023/08/29 02:39

トランザクションのテストはsleepなどと絡めて遅延を発生させないと多少大量のデータを発行しても捌かれてしまうような気がしますが
kutou

2023/08/29 06:56

そうすると一般的にはトランザクションのテストは実施しないのでしょうか。 負荷テストを行いたいわけではないので、ステップモードで確認することを検討します。
yambejp

2023/08/29 07:04

遅延テスト用の仕組みをあらかじめ組み込んでおくということです。
kutou

2023/08/29 07:13

最大値取得処理 ~ 新規登録 の間の部分に遅延を挟み込んでおき、その遅延時間内に別の登録処理を走らせれば問題の再現ができ、且つトランザクション設置後の挙動の改善も観測できる、という意味でしょうか? それでしたらできそうです!ありがとうございます!
yambejp

2023/08/29 07:44

トランザクションのテストパターンを記載しておきました
guest

回答1

0

ベストアンサー

参考

SQL

1create table tbl (id1 int primary key auto_increment,id2 int,val int); 2insert into tbl(id2,val) values 3(1,100), 4(2,200), 5(3,300);

に対して、遅延のトランザクションのテストは3パターンあります

パターン1

SQL

1/*先発実行*/ 2start transaction; 3select id2 from tbl for update; 4select sleep(5); 5insert into tbl(id2,val) values 6((select id2 from (select max(id2)+1 as id2 from tbl) as dummy),400), 7((select id2 from (select max(id2)+1 as id2 from tbl) as dummy),500); 8commit; 9 10/*後発実行*/ 11insert into tbl(id2,val) values 12((select id2 from (select max(id2)+1 as id2 from tbl) as dummy),600), 13((select id2 from (select max(id2)+1 as id2 from tbl) as dummy),700);

パターン2

SQL

1/*先発実行*/ 2start transaction; 3select id2 from tbl for update; 4insert into tbl(id2,val) values 5((select id2 from (select max(id2)+1 as id2 from tbl) as dummy),400), 6((select id2 from (select max(id2)+1 as id2 from tbl) as dummy),500); 7select sleep(5); 8commit; 9 10/*後発実行*/ 11insert into tbl(id2,val) values 12((select id2 from (select max(id2)+1 as id2 from tbl) as dummy),600), 13((select id2 from (select max(id2)+1 as id2 from tbl) as dummy),700);

パターン3

SQL

1/*先発実行*/ 2start transaction; 3select sleep(5); 4select id2 from tbl for update; 5insert into tbl(id2,val) values 6((select id2 from (select max(id2)+1 as id2 from tbl) as dummy),400), 7((select id2 from (select max(id2)+1 as id2 from tbl) as dummy),500); 8commit; 9 10/*後発実行*/ 11insert into tbl(id2,val) values 12((select id2 from (select max(id2)+1 as id2 from tbl) as dummy),600), 13((select id2 from (select max(id2)+1 as id2 from tbl) as dummy),700);

トランザクションの考え方からすれば遅延はパターン1に限られます
ただし実質パターン2でも問題ないでしょう
パターン3のようにfor updateの前に遅延が発生した場合は、後発クエリのほうが先行して実行される可能性があります。
したがって後発クエリもトランザクションで実行し、優先順位を確定させてください

投稿2023/08/29 07:34

編集2023/08/29 07:40
yambejp

総合スコア114843

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問