我正在我正在开发的网站上实施PayPal付款标准。问题与PayPal无关,我只想通过我的真实问题提出这个问题。
PayPal可以通过两种方式通知您的服务器付款:
问题是,您无法确定首先发生哪一个:
无论先发生什么,我都想确定我没有两次处理交易。 因此,在这两种情况下,我都会查询我的数据库,而不是来自paypal的交易ID(实际上付款状态......但现在无关紧要),看看我是否已经保存并处理了该交易。如果没有,我处理它,并将事务ID与其他事务详细信息保存到我的数据库中。
问题
如果我开始处理第一个请求会发生什么(让它成为PDT ..那么用户被重定向回我的网站,但我的服务器还没有被IPN通知),但在我实际将事务保存到数据库,第二个(IPN)请求到达,它也会尝试处理事务,因为它没有在数据库中找到它。
我很想确保在将事务写入数据库时,没有其他查询可以读取该表,查找给定的事务ID。
我正在使用InnoDB,并且在写入时不想锁定整个表。 这可以简单地通过交易解决,我可以“手动”锁定那一行吗?我真的很困惑,我希望一些更有经验的mysql开发人员可以帮助我解决问题并解决问题。
答案 0 :(得分:1)
本机数据库锁在Web上下文中几乎无用,特别是在这种情况下。 MySQL连接通常不是以持久方式完成的 - 当脚本关闭时,MySQL连接也会释放,所有锁都会被释放,并且任何正在进行的事务都会被回滚。
e.g。
情况1:您将用户引导至paypal的网站以完成购买
当他们离开paypal时,通过http重定向发送的脚本将终止并关闭。锁/交易被释放/回滚,他们回到了处女"关于数据库的状态。他们的记录不再被锁定。
情况2:Paypal执行服务器到服务器的响应。这将通过完全独立的HTTP连接完成,完全不同于用户与服务器建立的连接。这意味着您在yourserver< - >用户连接中建立的任何锁定都将与paypal< - > yourserver会话不同,并且paypal响应将遇到锁定的表格。当然,没有办法预测PayPal响应何时进入。如果网络神对你微笑并且paypal没有被淹没,你会很快得到响应,并且可能在用户< - > ;你的联系仍然是开放的。如果事情很慢并且响应延迟,则响应 MAY 会遇到未锁定的表/行,因为用户< - >服务器会话已完成。
你 COULD 使用持久的MySQL连接,但它们开启了另一个痛苦的世界。例如考虑一下你的脚本有一个在处理过程中被触发的bug的情况。你连接,做一些事务工作,设置一些锁...然后脚本死了。因为MySQL连接是持久的,所以MySQL不会看到客户端脚本已经死亡,并且它将保持事务/锁在飞行中。但是连接仍然在那里,在共享池中等待另一个会话来接收它。当它总是如此时,新的剧本不知道它已经得到了这个陈旧的陈旧的#34;连接。它会步入一堆乱七八糟的锁和交易的中间。你可以很容易地陷入这样的死锁状态,因为你的错误脚本已经在整个系统中丢弃垃圾,而其他脚本无法应对垃圾。
基本上,除非您在系统顶部实施自己的锁定机制,例如UPDATE users SET locked=1 WHERE id=XXX
,您不能在Web上下文中使用本机数据库锁定机制,除了每个脚本的1-shot-contexts。绝不应该尝试锁定多个独立请求。