バグ報告 > その他 > 在庫戻し処理の重複 |
その他
スレッド表示 | 古いものから | 前のトピック | 次のトピック | 下へ |
投稿者 | スレッド |
---|---|
maekawapis |
投稿日時: 2014/9/23 20:23
対応状況: −−−
|
新米 登録日: 2014/9/11 居住地: 投稿: 6 |
Re: 在庫戻し処理の重複【別対策案】 遅くなりましたが、別の対処法が見つかりました。
cronで行おうとしていましたが、 checkDbMyPendignOrderやcheckSessionPendingOrderがセッションを使っているため、 cronから触るのはよくないと考え、別の対処法を検討しました。 同タイミングだとselectで同じデータが2つ取れてしまうのが根本原因なので、ロックをかけるようにする方法です。 postgresであれば、FOR UPDATEをselect文に追記することで、行ロックが行えます。 ※他DBにも同様の機能はあるかと思います。
これでselect後にsleepを入れて恣意的に重複させても 後から入ったcheck*****PendignOrderは 先のトランザクションがcommitされるまで待たされ、 select結果として決済処理中のデータを取得できないようになります。 全ての影響は検証できていませんが、 みなさんのご意見伺いたいです。 以下、SC_Helper_Purchaseの最後の4メソッドです。
|
maekawapis |
投稿日時: 2014/9/12 15:30
対応状況: 解決済
|
新米 登録日: 2014/9/11 居住地: 投稿: 6 |
Re: 在庫戻し処理の重複 yona様
上記の件、理解しました。 弊社でもcron化で対応しようと思います。 皆様ありがとうございました。 余裕があればソース開示しようと思います。 以上、よろしくお願いします。 |
yona |
投稿日時: 2014/9/12 12:36
対応状況: −−−
|
半人前 登録日: 2012/2/10 居住地: 投稿: 25 |
Re: 在庫戻し処理の重複 やっぱりアクセストリガーだと制御が難しそうですよね。
bratech様のようにcronでの処理はうまく使えれば改善できそうですが、 ECCUBEには反映は無理そうですね; >トランザクションの開始、コミットによるロックがうまく効いていない印象です。 begin/commitはエラーなどの場合にデータ不整合を防ぐために 意図的にrollbackをかけられるようにする仕組みなのでちょっと違う気がします。 >cronにしても管理画面からのキャンセル処理と同タイミングになってしまえば、同じ現象が起きないでしょうか? 決済処理中で残ってしまった受注をキャンセルするということでしょうか。 これはもう、 「管理画面からは決済処理中の受注を弄らない」、 「既存の受注を決済処理中にしない」ようにするしかないのではないかと; これらのロールバック処理がうまく動けば、特に運営者が意識せずとも片付けられると思いますので。 機会損失が気になる、ということであれば、 有効期間(PENDING_ORDER_CANCEL_TIME)を短くすることで解決しませんか。 |
maekawapis |
投稿日時: 2014/9/12 11:37
対応状況: −−−
|
新米 登録日: 2014/9/11 居住地: 投稿: 6 |
Re: 在庫戻し処理の重複 ご連絡ありがとうございます。
PENDING_ORDER_CANCEL_FLAGをfalseにした場合は 決済処理中、在庫が減ったままの受注データが残り、 管理画面からキャンセル&在庫戻しまたは削除処理を行うようになるかと思います。 ログで確認したところ、cancelPendingOrderによる在庫戻しが 1ヶ月で300件程度発生しているので、運用が回るか怪しいです。 それでも売り越してしまうよりは良いかもしれませんが... 検討させていただきます。 |
maekawapis |
投稿日時: 2014/9/12 11:30
対応状況: −−−
|
新米 登録日: 2014/9/11 居住地: 投稿: 6 |
Re: 在庫戻し処理の重複 情報のご共有ありがとうございます。
やはり同現象は起きるのですね。 トランザクションの開始、コミットによるロックがうまく効いていない印象です。 cronにしても管理画面からのキャンセル処理と同タイミングになってしまえば、同じ現象が起きないでしょうか? |
bratech |
投稿日時: 2014/9/12 11:12
対応状況: −−−
|
長老 登録日: 2008/11/28 居住地: 福岡 投稿: 223 |
Re: 在庫戻し処理の重複 こちらの件ですが
アクセス集中が起こりサーバの処理が重くなったような状態を疑似的に作り、テストした事がございます。 その結果yona様のおっしゃる通り、複数回の巻き戻しが発生してしまう事を確認しております。 例えばcheckDbAllPendingOrderなどのチェック処理が仮に10秒かかったとします。 その10秒間に例えば20回アクセスがあったとしますと 20回分在庫の巻き戻しが行われてしまいます。 弊社ではアクセスをトリガーにするのではなく、 cronを利用してチェック処理を必ず1回だけにするようにする事で対応しております。 ご参考になれば幸いです。
|
yuh |
投稿日時: 2014/9/12 10:34
対応状況: −−−
|
神 登録日: 2013/1/9 居住地: 大阪 投稿: 1819 |
Re: 在庫戻し処理の重複 思いっきり使用されてましたね。
すみません。 とりあえずなんとかするのであれば PENDING_ORDER_CANCEL_FLAGをfalseにして対応するとかですかね。 |
maekawapis |
投稿日時: 2014/9/12 10:06
対応状況: −−−
|
新米 登録日: 2014/9/11 居住地: 投稿: 6 |
Re: 在庫戻し処理の重複 ご返信ありがとうございます。
私もyona様のおっしゃる現象ではないかと考えております。 決済モジュールは以下になります。 ペイジェント決済モジュール(2.13系) 導入バーション 3.0.2 モジュール内を調査しましたが、以下はともに呼ばれていません。 cancelPendingOrder checkDbAllPendingOrder サイトのページビューは1日だいたい3万ビュー程度です。 |
yona |
投稿日時: 2014/9/12 9:42
対応状況: −−−
|
半人前 登録日: 2012/2/10 居住地: 投稿: 25 |
Re: 在庫戻し処理の重複 2.13系であれば、受注が完了しないままで「決済処理中」として残ってしまった受注を戻すために、
cancelPendingOrder の呼び出しを主要なページに埋め込んであるようです。 Z:\eccube-2.13.1\data\class\helper\SC_Helper_Purchase.php(1349,21) [UTF-8]: public function cancelPendingOrder($cancel_flg) Z:\eccube-2.13.1\data\class\pages\LC_Page_Index.php(66,23) [UTF-8]: $objPurchase->cancelPendingOrder(PENDING_ORDER_CANCEL_FLAG); Z:\eccube-2.13.1\data\class\pages\cart\LC_Page_Cart.php(78,23) [UTF-8]: $objPurchase->cancelPendingOrder(PENDING_ORDER_CANCEL_FLAG); Z:\eccube-2.13.1\data\class\pages\entry\LC_Page_Entry.php(79,23) [UTF-8]: $objPurchase->cancelPendingOrder(PENDING_ORDER_CANCEL_FLAG); Z:\eccube-2.13.1\data\class\pages\entry\LC_Page_Entry_Kiyaku.php(67,23) [UTF-8]: $objPurchase->cancelPendingOrder(PENDING_ORDER_CANCEL_FLAG); Z:\eccube-2.13.1\data\class\pages\frontparts\LC_Page_FrontParts_LoginCheck.php(68,23) [UTF-8]: $objPurchase->cancelPendingOrder(PENDING_ORDER_CANCEL_FLAG); Z:\eccube-2.13.1\data\class\pages\mypage\LC_Page_Mypage.php(77,23) [UTF-8]: $objPurchase->cancelPendingOrder(PENDING_ORDER_CANCEL_FLAG); Z:\eccube-2.13.1\data\class\pages\mypage\LC_Page_Mypage_History.php(75,23) [UTF-8]: $objPurchase->cancelPendingOrder(PENDING_ORDER_CANCEL_FLAG); Z:\eccube-2.13.1\data\class\pages\mypage\LC_Page_Mypage_Login.php(65,23) [UTF-8]: $objPurchase->cancelPendingOrder(PENDING_ORDER_CANCEL_FLAG); Z:\eccube-2.13.1\data\class\pages\mypage\LC_Page_Mypage_Order.php(65,23) [UTF-8]: $objPurchase->cancelPendingOrder(PENDING_ORDER_CANCEL_FLAG); Z:\eccube-2.13.1\data\class\pages\products\LC_Page_Products_Detail.php(103,23) [UTF-8]: $objPurchase->cancelPendingOrder(PENDING_ORDER_CANCEL_FLAG); Z:\eccube-2.13.1\data\class\pages\products\LC_Page_Products_List.php(96,23) [UTF-8]: $objPurchase->cancelPendingOrder(PENDING_ORDER_CANCEL_FLAG); Z:\eccube-2.13.1\data\class\pages\shopping\LC_Page_Shopping.php(80,23) [UTF-8]: $objPurchase->cancelPendingOrder(PENDING_ORDER_CANCEL_FLAG); Z:\eccube-2.13.1\data\class\pages\shopping\LC_Page_Shopping_Confirm.php(76,23) [UTF-8]: $objPurchase->cancelPendingOrder(PENDING_ORDER_CANCEL_FLAG); Z:\eccube-2.13.1\data\class\pages\shopping\LC_Page_Shopping_Deliv.php(71,23) [UTF-8]: $objPurchase->cancelPendingOrder(PENDING_ORDER_CANCEL_FLAG); Z:\eccube-2.13.1\data\class\pages\shopping\LC_Page_Shopping_Multiple.php(68,23) [UTF-8]: $objPurchase->cancelPendingOrder(PENDING_ORDER_CANCEL_FLAG); Z:\eccube-2.13.1\data\class\pages\shopping\LC_Page_Shopping_Payment.php(76,23) [UTF-8]: $objPurchase->cancelPendingOrder(PENDING_ORDER_CANCEL_FLAG); 抜粋されたログを見る限り、cancelPendingOrder から呼ばれる checkDbAllPendingOrder の処理により受注が戻されているようですが、 アクセスがトリガーになっているので、アクセスが集中したりすれば、 タイミングによってはmaekawapis様のような事象が発生する可能性は0でない気がするのですがいかがでしょうか... 決済モジュールも同時に調査していただく必要がありそうですが。 |
yuh |
投稿日時: 2014/9/11 23:11
対応状況: −−−
|
神 登録日: 2013/1/9 居住地: 大阪 投稿: 1819 |
Re: 在庫戻し処理の重複 cancelPendingOrderに関しては使われてなさそうなんですが、ご使用の決済モジュールの中で使用されているかもしれないですね。
決済モジュールの会社へ問い合わせたほうがよろしいかと思います。 引用: ご確認していただき、問題があるようでしたら お急ぎであれば制作会社様の方へお問い合わせください。 |
(1) 2 » |
スレッド表示 | 古いものから | 前のトピック | 次のトピック | トップ |