经典ASP / VBScript - 插入后偶尔会返回错误的ID

时间:2014-05-02 11:21:56

标签: ajax ms-access vbscript asp-classic

我工作的公司正在举办筹款活动,并要求我整理一个小型网络应用程序,通过PayPal接受捐款。这听起来很简单,但截止日期很紧,所以我决定挖掘一下我在10年前在Classic ASP / VBScript中创建的类似东西并重复使用它(以及Access数据库)。但随后需求发生了变化并变得更加复杂(尽管截止日期相同),而且,为了简短说明,我最终得到了一些代码和应用程​​序似乎工作正常...直到今天,当用户报告在应用程序的“谢谢”页面上看到错误的数据。我很清楚,在将记录插入数据库后的某个时刻,代码偶尔会返回错误的id,但我无法复制错误或在代码中发现问题,我希望有人可能能够帮助我。

用最简单的术语来说,这是应用程序的工作原理:

  1. 用户可以选择注册三个不同的活动,并且必须进行PayPal捐赠才能参与他选择的活动。他可以做出各种额外的选择,这取决于他报名的事件。所以基本上,用户填写了一个标准的html表单,后台还有一堆jQuery内容可以帮助引导用户完成各种选择。
  2. 一旦用户完成了所有必需的选择并点击“提交”按钮,我就使用jQuery向Classic ASP / VBScript页面发送ajax调用,该页面将用户的数据插入Access数据库并返回id新插入的记录作为json响应。
  3. ajax success函数获取新id,将其插入隐藏的PayPal表单上名为“item_number”的字段中,然后将PayPal表单提交给PayPal。然后,用户将被带到PayPal进行付款。
  4. 我设置了PayPal的即时付款通知功能,以便在用户付款时,会向我们服务器上的监听器发送通知。通知包含查询字符串中的item_number,侦听器获取item_number,返回Access数据库并更新该记录以显示用户实际已付款。
  5. 最后,PayPal将用户返回到我们服务器上的感谢页面。感谢页面选取item_number查询字符串,在Access数据库中查询与该id匹配的记录,并显示用户已注册的任何内容的确认(这是“谢谢”页面。)
  6. 问题在于,在将数据插入数据库(正确插入数据)后,偶尔在步骤2中,返回错误的id,这反过来又对其余步骤产生不利影响。另一个问题是,有时当PayPal将用户返回到“谢谢”页面时,它会将item_number查询字符串附加两次,这似乎会在服务器上引发500错误...因此用户获得500页而不是谢谢。起初我想可能有两个人一次注册而Access只是跛脚,但我能够确认当时只有一个用户注册了。

    我认为问题必须出现在第2步的代码中,但我完全错过了它。这是代码(我在这里遗漏了大部分字段以节省空间):

    'Declare field names
    Dim Email
    Dim EventType
    
    'Declare variable for the id of the inserted record
    Dim currentId
    
    Email = Request.Form("Email")
    EventType = Request.Form("EventType")
    
    'if EventType = tournament, then check if user already registered
    If EventType = "tournament" Then
        Dim rscheckregistration
        Dim rscheckregistration_cmd
        Dim checkRegistration
        Dim hasAlreadyRegistered
    
        hasAlreadyRegistered = 0
    
        Set rscheckregistration_cmd = Server.CreateObject ("ADODB.Command")
        rscheckregistration_cmd.ActiveConnection = connregistration
        rscheckregistration_cmd.CommandText = "SELECT COUNT(*) AS Total FROM tournament WHERE EventType = 'tournament' AND Email = '" & Email & "'" 
        rscheckregistration_cmd.Prepared = true
    
        Set rscheckregistration = rscheckregistration_cmd.Execute
    
        checkRegistration = rscheckregistration("Total")
    
        rscheckregistration.Close
        Set rscheckregistration = Nothing
    
        if checkRegistration > 0 Then 
            hasAlreadyRegistered = 1
        end if
    
        'do not allow user to register more than once
        if hasAlreadyRegistered = 1 Then
            Response.ContentType = "application/json"
            Response.Write("{ ""type"":""Already Registered""}")
        end if
    
        if hasAlreadyRegistered = 0 Then
            Set rsregister = Server.CreateObject("ADODB.Recordset")
            rsregister.ActiveConnection = connregistration
            rsregister.Source = "SELECT * FROM tournament"
            rsregister.CursorType = 2
            rsregister.LockType = 3
            rsregister.CursorLocation = 3
            rsregister.Open()
    
            rsregister.AddNew
    
            rsregister.Fields("Email") = Email
            rsregister.Fields("EventType") = "tournament"
    
            'get the id of the record that was just inserted
            rsregister.Update
            bookmark = rsregister.absolutePosition
            rsregister.Requery
            rsregister.absolutePosition = bookmark
            currentId = rsregister("TournamentId")
    
            rsregister.Close
            Set rsregister = Nothing
            Response.ContentType = "application/json"
            Response.Write("{ ""type"":" & currentId & "}")
        end if
    
    'handle EventType = raffle and and EventType = casino
    Else 
        Set rsregister = Server.CreateObject("ADODB.Recordset")
        rsregister.ActiveConnection = connregistration
        rsregister.Source = "SELECT * FROM tournament"
        rsregister.CursorType = 2
        rsregister.LockType = 3
        rsregister.CursorLocation = 3
        rsregister.Open()
    
        'insert the record
        rsregister.AddNew
    
        rsregister.Fields("Email") = Email
        rsregister.Fields("EventType") = EventType
    
        'get the id of the newly inserted record
        rsregister.Update
        bookmark = rsregister.absolutePosition
        rsregister.Requery
        rsregister.absolutePosition = bookmark
        currentId = rsregister("TournamentId")
    
        rsregister.Close
        Set rsregister = Nothing
        Response.ContentType = "application/json"
        Response.Write("{ ""type"":" & currentId & "}")
    End if
    

1 个答案:

答案 0 :(得分:2)

不确定为什么需要Recordset.Requery()来获取TournamentId这也应该可以正常工作(取决于您的连接,但OLEDB和ODBC应该支持)。

Set rsregister = Server.CreateObject("ADODB.Recordset")
rsregister.ActiveConnection = connregistration
rsregister.Source = "SELECT * FROM tournament"
rsregister.CursorType = 1 'adOpenKeyset
rsregister.LockType = 3 'adLockOptimistic
rsregister.Open()

'insert the record
rsregister.AddNew

rsregister.Fields("Email") = Email
rsregister.Fields("EventType") = EventType

'get the id of the newly inserted record
rsregister.Update
currentId = rsregister("TournamentId")

rsregister.Close
Set rsregister = Nothing
Response.ContentType = "application/json"
Response.Write("{ ""type"":" & currentId & "}")