4

同じ方法論 (同じコードではない) を使用しているときに、私が取り組んできたいくつかのシステムで断続的なエラーが発生し、同じリクエストで構造体を作成して使用することに問題が関連している可能性があると思いました。競合状態が発生する可能性があるかどうか疑問に思っていますか?

シナリオは次のとおりです。私たちは電子商取引システムで、製品、場合によっては製品のリストを見ています。問題のコードは、各製品に関連付けられた画像を、その画像の表示に使用できる構造体で返すように設計されています。

リクエストの開始時に、コードは問題のアイテムに関連付けられたデータベース レコードを探します。これらのレコードは、製品の画像を表しています。これらのレコードは、1 回の呼び出しで返されます (より正確には、さまざまな情報を含む構造体に整形されたCFQuery、呼び出しの結果を返す関数の呼び出し)。CFQuery

次に、コードは提供された画像構造体をループし、さまざまな情報を Local 構造体に追加します。リクエストの後半で、構造体のデータを使用して<img>タグに画像を表示します。また、JavaScript で使用する属性を<img>タグに入力します。data-

特定の画像がクエリによって正しく返されなかった場合 (通常は物理ファイルが見つからないため)、汎用のプレースホルダー画像を使用します。これは、構造体の作成をtry/catchブロック内に配置することによって行われます。

重要:これは機能します。

ただし、何が起こっているかというと、非常に断続的に、作成した構造体のノードを参照すると、ノードが存在しないことがわかり、CF がエラーをスローします。これはおそらく 1% の確率で発生し、同じページをリロードします。完全に動作します。

複数のシステム、複数のサーバー、ColdFusion の異なるバージョン (具体的には 8 & 10) で同じ問題が発生し、完全に異なるコードを使用して同様の結果が得られました。この問題を最初に見たシステムは、実際にFileExistsイメージ ファイルが利用可能であることを確認するために使用されていたので、問題はおそらくファイルシステムのボトルネックが原因であると考えました。システム - しかし、問題は解決しません。

私が考えることができる唯一のことは、構造体を作成し、後で同じリクエストでその構造体を使用すると、競合状態が発生する可能性があるということです。これにより、作成が完了する前に構造体のノードを参照します。ただし、ここではスレッドを使用していないため、それがどのように可能かはわかりません...他のアイデアはありません。

私が何をしているのかを示すためにいくつかのコードを以下に示しますが、まったく異なるシステムで同じ問題が発生することを考えると、問題があるのはコードではなく方法論だと思います.

<!--- Get product images --->
<cfset Local.stProductImages = Application.cfcParts.getPartImages(
        l_iItemID = Arguments.pid
) />


<!--- Loop through images --->
<cfloop list="#ListSort(structKeyList(Local.stProductImages['item_' & Arguments.pid]), 'text')#" index="i">
    <cftry>
        <cfset Local['ImageURL_' & i & '_Large']    = Local.stProductImages['item_' & Local.arguments.pid][i].large_watermarked.URL />
        <cfcatch>
            <cfset Local['ImageURL_' & i & '_Large']    = Application.com.Images.getMissingImages().large />
        </cfcatch>
    </cftry>                        
    <cftry>
        <cfset Local['ImageURL_' & i & '_Med']      = Local.stProductImages['item_' & Local.arguments.pid][i].med.URL />
        <cfcatch>
            <cfset Local['ImageURL_' & i & '_Med']      = Application.com.Images.getMissingImages().med />
        </cfcatch>
    </cftry>                        
    <cftry>
        <cfset Local['ImageURL_' & i & '_Small']        = Local.stProductImages['item_' & Local.arguments.pid][i].small.URL />
        <cfcatch>
            <cfset Local['ImageURL_' & i & '_Small']        = Application.com.Images.getMissingImages().small />
        </cfcatch>
    </cftry>                        

    <img class          = "altProdImg<cfif i EQ 'image_03'> endImage</cfif>" 
        src             = "#Local['ImageURL_' & i & '_Small']#" 
        image           = "#i#" 
        alt             = ""
        data-imgsmall   = "#Local['ImageURL_' & i & '_Small']#"
        data-imgmed     = "#Local['ImageURL_' & i & '_Med']#"
        data-imglarge   = "#Local['ImageURL_' & i & '_Large']#"
        data-imgnum     = "#i#"
        data-pid        = "#Arguments.pid#"
    />
</cfloop>

<img>上記のコードで作成されたノードを参照すると、タグでエラーが発生します-次のようなもの:

エレメント ImageURL_image_02_Large は、タイプ クラス coldfusion.runtime.LocalScope の Java オブジェクトで定義されていません。

しかし、ごくたまにしかありません...リロードすると、毎回完全に機能します。

それで... 壮大な長さの質問で申し訳ありませんが、これがどのように発生するかわかる人はいますか?

4

1 に答える 1

3

コメントからの回答...

あなたが説明する動作は var スコープではないことを示しているためindex="local.i"、cfloop タグで使用するのと同じくらい簡単に修正できます (変数を書き込むときにのみスコープが必要です)。


補足:コードを使用せずに関数内にいるかどうかを確認する比較的簡単な方法は、エラー (つまり<cfthrow message="where am i?" />) をスローしてからスタック トレースを確認することです。 (現在のテンプレートにその兆候が見られない場合でも)。coldfusion.runtime.UDFMethod$funcSTUFF.runFunction(filename:line)

于 2013-11-12T13:37:44.680 に答える