バージョン選択

フォーラム

メニュー

オンライン状況

73 人のユーザが現在オンラインです。 (60 人のユーザが フォーラム を参照しています。)
登録ユーザ: 0
ゲスト: 73
もっと...

サイト内検索

バグ報告 > フロント機能 > 携帯で注文する時、二重注文が入ってしまうのは?

フロント機能

新規スレッドを追加する

スレッド表示 | 新しいものから 前のトピック | 次のトピック | 下へ
投稿者 スレッド
pop2joa
投稿日時: 2010/6/8 0:14
対応状況: −−−
新米
登録日: 2010/6/7
居住地:
投稿: 6
携帯で注文する時、二重注文が入ってしまうのは?
携帯で注文する時、サーバーの応答とかが遅くなるとユーザとしては2〜3回押すあ場合があると思いますが、その場合、同じ注文が2〜3個入っちゃって困ってます。

【現象】
パタンとしては2種類があります。
?同じ注文が2〜3個発生し、dtb_orderのdel_flgは1個だけが生きている場合


?同じ注文が2〜3個発生し、del_flgが全部生きている場合(del_flg = 0)

そもそもECCUBEってこちらの処理は出来てないですかね?
ご返信お待ちしますので宜しくお願い致します。


【システム情報】
EC-CUBE 2.4.1
PHP 5.1.6
PostgreSQL 8.1.11
pop2joa
投稿日時: 2010/6/8 0:17
対応状況: −−−
新米
登録日: 2010/6/7
居住地:
投稿: 6
Re: 携帯で注文する時、二重注文が入ってしまうのは?
http://xoops.ec-cube.net/modules/newbb/viewtopic.php?viewmode=flat&order=ASC&topic_id=4143&forum=9

現象としては上記の場合が一番近いかと思います。
AMUAMU
投稿日時: 2010/6/8 15:47
対応状況: −−−
登録日: 2009/5/2
居住地: 東京都
投稿: 2712
二重注文の不具合
この問題、詳しく調べてみました。

今まで当方の顧客では発生経験がなく、深く気にしていませんでしたが、たまたまlfDoCompleteを大幅に修正する件があり改めて調べたところ、標準のEC-CUBEのトランザクションの利用方法に問題があり、この現象は不具合ではないかと考えています。

原因として考えているのはdtb_order_tempの読み取り行に対して明示的ロックをしていないことではないかと思います。

この結果、多重読み込みへの対応は本来、pop2joaさんご指摘の?のパターンを想定しているように見えますが、?のように複数の注文に分裂するタイミングがありえます。
?のパターンも起きないように出来るとは思いますが改編箇所多いですね・・・

まだ調べていませんが広範囲に同じ問題を抱えている可能性があります。

なお、これはMySQLでもPostgreSQLでも起こると思います。(どちらも明示的な行ロックが確か必要なはず)

少々MySQL、PostgreSQLのトランザクション制御に関する深い所で、実装系差違部分もありますし(例えば、もし同様の手順をDB2で組むと発生しないはず)、難解ですが早々に治したい不具合かもしれません。

私の勘違いではないかどうか、他の識者の方々の見解もいただければと思います。


----------------
EC-CUBE公式エヴァンジェリスト
EC-CUBEインテグレートパートナー (株)スピリット・オブ
移転・拡張・高速化・問題解決
各種カスタマイズ・支援依頼承ります。

[url=h

pop2joa
投稿日時: 2010/6/8 18:02
対応状況: −−−
新米
登録日: 2010/6/7
居住地:
投稿: 6
Re: 二重注文の不具合
AMUAMUさん!!
ご応答ありがとうございます〜


教えていただいた通り、
「明示的な行ロック」を調べましてSC_Helper_DB.phpのsfGetOrderTempの
「$where = "order_temp_id = ?"」を「$where = "order_temp_id = ? FOR UPDATE"」に変えたら、?のパターンの「del_flg」は1個だけが「0」になるようになりました。正しいですかね?他に問題が発生するんじゃないかと心配ですが、、

?のパターンに対してはもうちょっと調べてみます。

本当にありがとうございます〜


↓↓以下参照サイト
http://www.geocities.jp/sugachan1973/doc/funto60.html
AMUAMU
投稿日時: 2010/6/8 18:17
対応状況: −−−
登録日: 2009/5/2
居住地: 東京都
投稿: 2712
Re: 二重注文の不具合
対応方法としてはSELECT FOR UPDATE文を足す方向で正しいと思いますが、SC_Helper_DBは共通ヘルパー関数なので他のページの処理で使われたときにどのような影響が出るかという問題と、SC_Queryオブジェクトを引き回していないのでルール的には正しくない問題(実際は同じ接続を使い回すので大丈夫なのかな?)がありますので、十分に調べた方がいいかもしれません。

当方の手元では取り急ぎの対応として、気付いたところをHelper関数呼び出しから各クラス内に専用で作る読み込みクラス内関数に書き換える方針で考えています。

なお細かく精査していませんが、上記の対応をすれば、ご指摘の?のパターンは発生しなくなると思います。


----------------
EC-CUBE公式エヴァンジェリスト
EC-CUBEインテグレートパートナー (株)スピリット・オブ
移転・拡張・高速化・問題解決
各種カスタマイズ・支援依頼承ります。

[url=h

pop2joa
投稿日時: 2010/6/9 10:41
対応状況: −−−
新米
登録日: 2010/6/7
居住地:
投稿: 6
Re: 二重注文の不具合
AMUAMUさんがおしゃった通り、ヘルパー関数は他のページでも使われてるので確かどのような影響が出るかという問題はありますね。

引用:

当方の手元では取り急ぎの対応として、気付いたところをHelper関数呼び出しから各クラス内に専用で作る読み込みクラス内関数に書き換える方針で考えています。


対策としては「SC_Helper_DB.php」内に新しい関数(sfGetOrderTempと似たような)を作って「LC_Page_Shopping_Complete.php」のlfDoCompleteだけ新しい関数みるようにしようと思っておりますが、これで大丈夫ですようね?

ちなみに
引用:

SC_Queryオブジェクトを引き回していないのでルール的には正しくない問題

実際、sfGetOrderTemp内ではSC_Queryを引き回しているみたいですが、僕の勘違いですかね?それとも「FOR UPDATE」もSC_Queryを引き回すように入れないといけないっていう話?ですか?
AMUAMU
投稿日時: 2010/6/9 11:43
対応状況: −−−
登録日: 2009/5/2
居住地: 東京都
投稿: 2712
Re: 二重注文の不具合
引用:
対策としては「SC_Helper_DB.php」内に新しい関数(sfGetOrderTempと似たような)を作って「LC_Page_Shopping_Complete.php」のlfDoCompleteだけ新しい関数みるようにしようと思っておりますが、これで大丈夫ですようね?

大丈夫だと思います。

引用:
実際、sfGetOrderTemp内ではSC_Queryを引き回しているみたいですが、僕の勘違いですかね?それとも「FOR UPDATE」もSC_Queryを引き回すように入れないといけないっていう話?ですか?


lfDoCompleteの引数にある$objQuery(トランザクションを発行したオブジェクト)を持ち回して利用するのが筋かなと思います。


----------------
EC-CUBE公式エヴァンジェリスト
EC-CUBEインテグレートパートナー (株)スピリット・オブ
移転・拡張・高速化・問題解決
各種カスタマイズ・支援依頼承ります。

[url=h

pop2joa
投稿日時: 2010/6/9 11:54
対応状況: −−−
新米
登録日: 2010/6/7
居住地:
投稿: 6
Re: 二重注文の不具合
結果としては
関数を追加してやってみましたが、lfDoComplete内だけだと効かないみたいですね。これはもうちょっと調べてみます。

一つ気づいたのですが、この方式だと注文のデータが2行以上できちゃって1行だけが有効になります。現行ポイントのところをSOAPClientで連動してるのでこれじゃ使えない状態になると思ってます。それで前AMUAMUさんがおしゃってた?のパターンも(1行だけが注文として入るように)起きないようにしたいですが、どこからみてみればいいですかね?

すみません。宜しくお願い致します!!
AMUAMU
投稿日時: 2010/6/9 12:21
対応状況: −−−
登録日: 2009/5/2
居住地: 東京都
投稿: 2712
Re: 二重注文の不具合
1行だけが注文として入るようにする方向性ですが、明示的な行ロックをきちんとかける前提で、いくつか例外パターンを実装する必要があると思います。
・行ロックが取得出来なかった時の例外処理
・order_tempの行データに既にdel_flgが立っていた場合の処理
・その他のアップデート処理での競合時の例外処理(ロックが正常にされていれば、トランザクション関係のエラーが発生するので)

例外時にはユーザーの再読込が考えられるので、表示上は普通に表示されるようにする処理。(order_tempから有効なorder_idを特定して、そのorder_idで表示だけ成立させる)

という感じでしょうか。
色々な所を確認する必要がありますが、基本はlfDoComplete前後からのスタートでしょうね・・・。


----------------
EC-CUBE公式エヴァンジェリスト
EC-CUBEインテグレートパートナー (株)スピリット・オブ
移転・拡張・高速化・問題解決
各種カスタマイズ・支援依頼承ります。

[url=h

ゲスト
投稿日時: 2012/9/8 20:56
対応状況: 確認中
Re: 二重注文の不具合
古いレスに返信ですみません。

こちらでは、モバイルページから購入した場合に、
注文ボタンを多重クリックで、注文完了メールは送信されるが、受注データが管理画面に反映されないという事象が再現できました。

古いバージョンを使用しているので、既に解決済みであれば
教えて頂けないでしょうか?

よろしくお願いいたします。
-----------------------------------------------------
EC-CUBEバージョン 2.4.3c
PHPバージョン PHP 5.3.6
DBバージョン PostgreSQL 8.4.7
-----------------------------------------------------
(1) 2 »
スレッド表示 | 新しいものから 前のトピック | 次のトピック | トップ


 



ログイン


EC-CUBE公式 Amazon Payプラグイン

統計情報

総メンバー数は88,288名です
総投稿数は109,688件です

投稿数ランキング

1
seasoft
7365
2
468
3217
3
AMUAMU
2712
4
nanasess
2303
5
umebius
2085
6
yuh
1818
7
h_tanaka
1610
8
red
1567
9
mcontact
1240
10
tsuji
958
11
fukap
907
12
shutta
835
13
tao_s
796
14 ramrun 789
15 karin 689
16 sumida 641
17
homan
633
18 DELIGHT 572
19
patapata
502
20
flealog
485


ネットショップの壺

EC-CUBEインテグレートパートナー

Copyright© EC-CUBE CO.,LTD. All Rights Reserved.