2010-10-05 4 views
0

Dans mon code, je fais une requête http (en utilisant cfhttp) et stocke le résultat dans une variable. La requête http renvoie - Je le sais parce que je consignerai l'heure de la demande et les résultats. Cependant, quelque chose semble parfois aller mal avec le stockage des résultats de la requête http (cfhttp.filecontent) dans une variable, car plus tard, lorsque je mets une autre variable à la première variable, la première variable génère parfois une erreur ("L'élément insurance_233 n'est pas défini dans une structure CFML référencée comme faisant partie d'une expression."). Quand je vide la variable de session, l'élément est, bien sûr, pas là. Je n'arrive pas à comprendre ce qui provoque l'erreur.La variable pour contenir les résultats de la requête http est indéfinie

Voici le code (légèrement modifié, mais en substance assez pour illustrer de quoi je parle.) La garniture a été ajoutée dans l'espoir que cela résoudrait l'erreur et j'ai ensuite changé "d'assurance" & #myNum # pour plus syntaxiquement correct « assurance # myNum # », mais pour cette illustration je l'ai laissé dans son état d'origine pour montrer comment il était la dernière fois que l'erreur a été lancé).

<cfloop query="myQuery"> <!--- one of the query columns is myNum---> 
    <cflock scope="session" type="exclusive" timeout="10"> 
     <cfset session.report.mydata["insurance_" & #myNum#] = cfhttp.filecontent> 
    </cflock> 
    <cfset request.report.mydata["insurance_" & #myNum#] = trim(session.report.mydata["insurance_" & #myNum#])> 
</cfloop> 
+0

Est-ce que cette frappe manquante signe une faute de frappe à la toute fin de myNum? Ce n'est pas dans votre code actuel, n'est-ce pas? –

+0

Oui c'est une typo-je vais le changer, merci! – dmr

Répondre

2

Vous ne verrouillez pas la logique responsable de la définition de la valeur de myNum. Si plusieurs demandes sont traitées en même temps, vous pourriez vous retrouver dans la situation suivante.

Request 1: sets myNum to 33 
Request 1: writes data to session using myNum as the index; i.e. session[33] 
Request 2: sets myNum to 34 
Request 1: reads data from session using myNum as the index; i.e. session[34] 
Request 2: writes data to session using myNum as the index; i.e. session[34] 

Ainsi, demande 1 tentatives de lecture d'un emplacement non défini parce que demande 2 a incrémentée l'index/myNum mais n'a pas écrit de données.

+0

Selon votre réponse, j'ai réalisé que l'échantillon de code que j'ai donné n'est pas tout à fait exact. myNum est vraiment lu à partir d'une requête que je suis en boucle ... Je vais modifier mon code. Si vous le pouvez, faites-moi savoir si votre réponse s'applique toujours. – dmr

+0

Bonne question. Je ne suis pas à cent pour cent, mais quand je travaille avec CFC, c'est une bonne pratique de le faire. ... . Toute variable dans L sera thread-safe donc la situation que j'ai décrite ne peut pas arriver. –

+0

Ce que j'ai fini par faire est lié à ce que vous avez indiqué. Au lieu de verrouiller chaque cfset, j'ai placé un cflock autour de la boucle entière. Il semble fonctionner correctement maintenant. Je vous remercie! – dmr

2

à moins que vous utilisez CF5 ou inférieur, vous n'avez pas besoin d'utiliser les verrous de portée. Je n'utilise plus de verrous sauf s'ils sont nommés verrous pour une condition de course spécifique. De plus, si vous verrouillez à 10 secondes sans que l'écriture ne soit terminée, l'écriture sera complètement ignorée et vous ne le saurez pas. C'est probablement ce qui se passe. Essayez d'ajouter "throwontimeout = true" au cflock et vous obtiendrez une erreur lorsque le timeout sera dépassé au lieu de simplement ignorer l'écriture.

+0

Avez-vous essayé de retirer le verrou pour voir si cela fonctionne? –

2

Si cela est dans un CFC, avez-vous écrit

<cfset var myNum=0> 

à un moment donné dans la même méthode?

1

Le code ci-dessus ne donne pas beaucoup de contexte, mais lisez-vous la session de la même portée d'application que vous l'écrivez?

Questions connexes