0

我有一个ColdFusion 8的问题,我发布堆栈溢出不久前Coldfusion 8 doing both CFIf and the CFElse statement ,我认为我已经缩小到一个MySQL问题,但(进一步调查),但我已经收窄它下降到多线程/每个会话的多个请求问题。 (这仍然可能是一个MYSQL的问题,但我不知道如何解决它)Coldfusion 8多线程并发

什么是真正的代码脚麻:

<cfif isValid("email", form.email)>  
    <cfquery name="check_user" datasource="#request.dsn#"> 
     SELECT var_username, var_password 
     FROM tbl_users 
     WHERE var_username = <cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="#FORM.EMAIL#"> 
     AND var_password = <cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="#FORM.PASSWORD#"> 
     </cfquery> 
    <cfif check_user.recordcount EQ 0> 
     <cfquery datasource="#request.dsn#" name="insertuser"> 
      INSERT INTO tbl_users (var_username, var_password)    VALUES 
      (<cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="#FORM.EMAIL#">,    <cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="#FORM.PASSWORD#">) 
     </cfquery> 
      <cflogin idletimeout="1800"> 
     <cfloginuser 
        name = "#FORM.email#" 
       password ="#FORM.password#" 
       roles = "0"> 
      </cflogin> 
     <cflocation addtoken="No" url="#request.secure_url#checkout.cfm"> 
    <cfelse> 
     <cfset client.error_message = "Your Email Address is already registered."> 
     <cflocation addtoken="No" url="#request.site_url#New-Account.html"> 
    </cfif> 
    <cfelse> 
    <cfset client.error_message = "Your Email Address is not Valid."> 
    <cflocation addtoken="No" url="#request.site_url#New-Account.html"> 
    </cfif> 

是存在由正在取得2个并发请求同一个用户。如果请求稍微交错,请求A将把用户插入到数据库中,但在请求A可以CFLOGINCFLOCATION之前,请求B获取CFIF通知数据库中已经存在用户,并创建CLIENT.ERROR_MESSAGECFLOCATION' s到New-Account.html。 但是,如果请求不交错,会发生什么情况是代码似乎有效,并将用户发送到checkout.cfm页面,但是在数据库中,用户会插入两次。

我已经采取措施来尝试解决此步骤:

1:同MySQL服务器中使用不同的数据库(通过改变数据源到我们具有相似/相同tbl_users其他网站之一)。相同的结果。

2:把网站放在不同的coldfusion 8/windows 2003服务器(但使用相同的MYSQL服务器)。相同的结果。

3:将一个

<cflock name="NewUser" timeout="30" type="EXCLUSIVE"> 

在代码的开头和

</cflock> 

在码的末尾。同样的结果。

我真的认为把CFLOCK放在代码上可以解决这个问题,但它没有,现在我不知道下一步该怎么做(但可能是因为我以前从未使用过CFLOCK,使用它错误)。有没有人有任何想法如何解决这个问题,以便只发送一个请求?或者为什么2个请求正在发送的任何想法? (我不认为它的pebkac,因为我是一个做测试的人,而且我没有按两次提交按钮)

另外,我使用的是Windows 2003的web服务器,带有coldfusion 8.还有一个单独的Windows 2003服务器与MySQL 5

回答

0

对不起我的等级不够高,只是张贴您的问题在下面留言...

我不知道为什么你得到两个或多个并发请求用户代码的这一部分。您是否正在使用AJAX或ColdFusion AJAX功能访问其他CFM文件?

我认为你的解决方案将是追踪为什么一个用户会多次击中该部分代码。

您可以使用<cflog>来跟踪如何调用这段代码。

+0

我不使用Coldfusion在本网站上提供的任何Ajax函数。我跑cflog,就像我说的,每个条目都有一个双重条目,这里是一个样本,它有电子邮件和密码试图添加 - “信息”,“jrpp-632”,“03/28/12“,”10:32:50“,”User [email protected] password“,”Information“,”jrpp-630“,”03/28/12“,”10:32:50“,, “用户[email protected]密码”' – 2012-03-28 14:34:22

+0

很好的使用cflog。我假设你有一个用户完成一次的登录表单,并单击提交按钮登录。现在我想到了,我的项目中有一个类似的问题。这是与IE。 IE允许用户通过垃圾邮件点击提交按钮,每次点击时,表单操作都会被调用。我的解决方案是放入一个小的JavaScript代码片段,以便在点击按钮时禁用/隐藏按钮。这可能是这种情况吗? – 2012-03-28 19:52:34

+0

不,因为我是进行测试并遇到问题的人,而且我没有多次触碰提交按钮。 (但是,这将是一个好主意,当我把代码生效时执行) – 2012-03-29 14:24:03

0

您正在构建一个并发应用程序。很高兴你在开发周期中尽早发现这个问题。当并发应用程序使用DBMS约束来管理它们的并发而不是您在示例中显示的那种代码时,它们的工作效果最佳。

我建议你切换到InnoDB如果你还没有使用它,然后设置你的tbl_users.var_username列作为一个主键,在数据库中有一个唯一的约束。

然后,从您的表中不要SELECT。只需要做INSERT。如果用户名已经存在,您将从<cfquery>插入操作中得到例外。适当处理它。如果INSERT正常工作,则只需添加一个新用户即可。如果失败,您尝试添加重复的用户,并且您可以在Web用户界面上呈现适当的响应。

+0

我正在使用InnoDB,并且我决定尝试你的方法,所以我在数据库中创建了var_username一个PK,并让代码执行INSERT,但是,它只是添加了另一个条目,无论用户是否具有该用户名。 (这可能是因为我已经为该表添加了另一个PK,它是一个Unique Auto Increase ID)。我不知道是否在桌上有两个PK会导致这种情况,但它不起作用。 – 2012-04-02 15:23:24

+0

没关系,没有正确应用SQLyog中的唯一密钥,现在我已经做了,它不再添加2个条目,但是现在看起来似乎存在使用此解决方案的其他一系列问题。我宁愿不用这种方法来解决这个问题,而是找到并发的根本原因并解决这个问题。 (但是,感谢您使用独特/插入方法,我将来可能会使用它,只要我解决这些问题) – 2012-04-02 15:50:44