我的Coldfusion 8出现了问题,我在不久前发布了Stack Overflow Coldfusion 8 doing both CFIf and the CFElse statement 我认为我已经缩小到一个mysql问题,但随着(进一步)进一步调查,我已经缩小到每个会话问题的多线程/多个请求。 (这可能仍然是一个MYSQL问题,但我不知道如何修复它)
代码确实出了什么问题:
<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可以CFLOGIN
和CFLOCATION
之前,请求B会在CFIF注意到数据库中已有用户,并将CLIENT.ERROR_MESSAGE
和CFLOCATION
创建为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
可以解决问题,但事实并非如此,现在我不知道下一步该做什么(但可能是因为我从未使用过{{} 1}}之前,我使用它错了)。有没有人有任何想法如何解决这个问题,以便只发送一个请求?或者为什么要发送2个请求的任何想法? (我不认为它是pebkac,因为我是那个进行测试的人,而且我没有按两次提交按钮)
另外,我使用的是带有coldfusion 8的Windows 2003 Web服务器。还有一个带有MYSQL 5的单独的Windows 2003服务器。
答案 0 :(得分:0)
抱歉,我的排名不够高,只能在您的问题下面发表评论......
我想知道你为什么要为该部分代码获得两个或更多用户并发请求。您是否使用AJAX或ColdFusion AJAX函数访问其他CFM文件?
我认为您的解决方案是追踪一个用户为何会多次点击该部分代码。
您可以使用&lt; cflog&gt;跟踪如何调用此部分代码。
答案 1 :(得分:0)
您正在构建并发应用程序。很高兴你在开发周期的早期发现了这个问题。并发应用程序在使用DBMS约束来管理其并发性而不是您在示例中显示的代码类型时效果最佳。
如果您尚未使用,我建议您切换到InnoDB
,然后将tbl_users.var_username
列设置为主键,并在数据库中使用唯一约束。
然后,不要从你的桌子SELECT
。只需做INSERT
即可。如果用户名已存在,您将从<cfquery>
插入操作中获得异常。妥善处理。如果INSERT
正常工作,您只需添加一个新用户即可。如果失败,您尝试添加重复的用户,并且可以在Web用户界面上显示相应的响应。