0

我正在我正在开发的网站中实施 PayPal 付款标准。这个问题与PayPal无关,我只是想通过我的实际问题提出这个问题。

PayPal 可以通过两种方式通知您的服务器有关付款:

  1. PayPal IPN - 每次付款后,PayPal 都会向包含交易详细信息的 url(由您选择)发送(服务器到服务器)通知。
  2. PayPal PDT - 付款后(如果您在您的 PP 帐户中设置),PayPal 会将用户重定向回您的网站,并在 url 中传递交易 ID,因此您可以向 PayPal 查询该交易以获取详细信息。

问题是,你不能确定哪个先发生:

  • 您的服务器是否会通过 IPN 通知
  • 将用户重定向回您的网站

无论哪个先发生,我都想确保我不会两次处理交易。因此,在这两种情况下,我都会根据来自 paypal 的交易 id(实际上是付款状态......但现在没关系)查询我的数据库,以查看我是否已经保存并处理了该交易。如果没有,我会处理它,并将交易 ID 与其他交易详细信息一起保存到我的数据库中。

问题

如果我开始处理第一个请求会发生什么(让它成为 PDT..so 用户被重定向回我的站点,但 IPN 尚未通知我的服务器),但在我实际将事务保存到数据库之前,第二个(IPN)请求到达,它也会尝试处理事务,因为它在数据库中找不到它。

我很想确保当我将事务写入数据库时​​,没有其他查询可以读取表,寻找给定的事务 id。

我正在使用 InnoDB,并且不想在写入时锁定整个表。这可以通过事务简单地解决吗,我是否要“手动”锁定该行?我真的很困惑,我希望一些更有经验的mysql开发人员可以帮助我弄清楚这一点并解决问题。

4

1 回答 1

1

本机数据库锁在 Web 上下文中几乎没有用,尤其是在这种情况下。MySQL 连接通常不会以持久的方式完成 - 当脚本关闭时,MySQL 连接和所有锁都会被释放,并且任何正在进行的事务都会回滚。

例如

情况1:你引导用户到paypal的网站完成购买

当他们离开贝宝时,通过 http 重定向发送的脚本将终止并关闭。锁/事务被释放/回滚,就数据库而言,它们回到“原始”状态。他们的记录不再被锁定。

情况 2:Paypal 进行服务器到服务器的响应。这将通过一个完全独立的 HTTP 连接完成,与用户建立到您的服务器的连接完全不同。这意味着您在 yourserver<->user 连接中建立的任何锁定都将不同于 paypal<->yourserver 会话,并且 paypal 响应将遇到锁定的表。当然,无法预测何时收到 paypal 响应。如果网络之神对您微笑并且 paypal 没有被淹没,您会很快得到响应,并且可能在用户<->您的连接仍处于打开状态时。如果事情很慢并且响应延迟,则该响应可能会遇到未锁定的表/行,因为用户<->服务器会话已完成。

可以使用持久的 MySQL 连接,但它们打开了另一个痛苦的世界。例如,考虑您的脚本有一个在处理过程中被触发的错误的情况。你连接,做一些交易工作,设置一些锁......然后脚本就死了。因为 MySQL 连接是持久的,所以 MySQL 不会看到客户端脚本已经死掉,它会保持事务/锁处于运行状态。但是连接仍然在那里,在共享池中等待另一个会话来接它。当它总是如此时,新脚本不知道它已经获得了这种旧的“陈旧”连接。它将进入一堆它不知道存在的锁和事务的中间。你可以很容易地让自己陷入这样的僵局,

基本上,除非您在系统顶部实现自己的锁定机制,例如UPDATE users SET locked=1 WHERE id=XXX,您不能在 Web 上下文中使用本机 DB 锁定机制,除非在 1-shot-per-script 上下文中。永远不要在多个独立的请求上尝试锁定。

于 2013-05-02T15:59:35.037 回答