Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/283.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何以可扩展的方式安全地实现银行/跨订单类型更新_Python_Google App Engine - Fatal编程技术网

Python 如何以可扩展的方式安全地实现银行/跨订单类型更新

Python 如何以可扩展的方式安全地实现银行/跨订单类型更新,python,google-app-engine,Python,Google App Engine,我正在谷歌appengine上做一个小项目,试图实现一个允许参与者买卖假货的网站,类似于股票市场,系统将实时显示买卖价差 举个简单的例子: 卖家下订单以8.00的价格出售10箱(订单1) 然后,买方下订单购买5箱,价格不超过9.00(订单2) 下第二个订单时,系统将需要执行多个任务,所有任务都取决于所有任务是否成功完成 从买方处获得支付箱子费用的资金(8.00 x 5),并将其交给卖方 从卖方处取出箱子(5)并交给买方 将订单更新为“已完成”(OID 2)或更新为“已部分完成”(OID 1

我正在谷歌appengine上做一个小项目,试图实现一个允许参与者买卖假货的网站,类似于股票市场,系统将实时显示买卖价差

举个简单的例子:

  • 卖家下订单以8.00的价格出售10箱(订单1)
  • 然后,买方下订单购买5箱,价格不超过9.00(订单2)
下第二个订单时,系统将需要执行多个任务,所有任务都取决于所有任务是否成功完成

  • 从买方处获得支付箱子费用的资金(8.00 x 5),并将其交给卖方
  • 从卖方处取出箱子(5)并交给买方
  • 将订单更新为“已完成”(OID 2)或更新为“已部分完成”(OID 1),以便它们不能重复匹配
  • 从每个参与者处收取费用,并将其添加到系统帐户中
如果我所需要的是把资金从一个参与者转移到另一个参与者,即使系统在中间失败,我也可以安全地做到这一点。但要确保上述所有任务正确完成,并在其中任何任务失败时回滚,在AppEngine中似乎过于复杂

此外,我的“订单簿”和订单匹配引擎现在是单线程的(使用互斥锁进行锁定)。这似乎违背了使用App engine的全部意义,但我不确定我是否找到了解决方法

所以(最后)-我的问题是:

  • 使用App Engine时,如果有多个步骤都取决于每个步骤是否正确完成,是否有最佳实践
  • 是否有人对如何允许订单簿多线程或保持单线程有任何建议?是否有一种最佳做法,即在扩展时不让此核心部分阻碍网站的使用?我曾考虑过使用任务对订单添加/更新/取消进行排队,以将书籍与直接参与者输入分开

谢谢你,我期待着你的帮助

对于偶然发现这一点的其他人-

现在,在Google App Engine中,似乎可以进行跨组交易:

这意味着您可以在单个事务中同时读取、执行逻辑,然后一次写入多个实体

我相信这解决了我在问题中提出的第一个问题

第二个问题——是否有办法让订单簿不是单线程的,仍然是开放的


谢谢大家!

我认为,如果您可以对商品上的订单进行排序,那么您就可以离线清除订单。所谓“离线”,我的意思是你可以在一天结束时来找我,告诉我订单的顺序,我可以告诉你发生了哪些交易。一个障碍是,如果一笔交易本应结清,而买方却没有资金怎么办?您可以通过两种方式解决此问题:

  • 把资金交给第三方保管,这样任何可以结算的订单都可以
  • 如果资金不可用,当您试图结算订单时,请放弃购买订单
  • 正如您所建议的,您可能需要跨实体的集团交易,以确保资金转账是正确的(即既不创建也不销毁资金)

    您可以按时间对订单排序(例如,paced_at=db.DateTimeProperty(auto_now_add=True))。如果两个订单有相同的时间,那么使用某种东西(最好是公平和确定的东西)打破僵局。在这里,数字id的散列(为了公平)(为了确定性)可能不是一个坏的选择

    应用程序引擎本质上是多线程的,因为一个应用程序可以有多个并发实例(但实例不一定是同一进程中的线程)。实例是自动创建的,目前无法将实例数限制为1。如果应用程序的状态在数据存储中(与本地内存、memecache或其他地方相反),并且事务正确,则应用程序将是“免费”多线程的。当然,您的事务的正确性并不是微不足道的


    另一个需要记住的工具是任务可以是事务性的。如果您想使用任务进行离线图书清算,这可能很有用。

    另外要澄清的是-我对App Engine中交易的理解是,它们仅限于单个实体组,但也许我弄错了,我只需要在事务中运行上面的内容就可以了?我想读一读Nick Johnson的这篇文章,谢谢Tim-到目前为止,这正是我实现事务的方式。它保证单向贸易要么立即失败,要么最终成功,而且它是以等幂的方式实现的。但是,对于这个项目,我需要一种方法来确保双向交易在一个步骤中失败,或者最终总是成功,除了将订单标记为已完成,以便它们不能被重复购买或出售。threading.Lock只会保护本地资源不被并发访问。它不会保护应用程序不同实例的并发访问。同步根本不违反“应用程序引擎方式”。如果需要同步访问,则需要使用诸如threading.Lock之类的同步机制。这基本上就是我正在做的-在添加或交易期间使用Memcache互斥来阻止书籍,在add期间将资金转移到托管/持有中,然后使用XG事务更新交易期间需要执行的4个并发任务-两次转账和两次订单更新。Memcache互斥是什么意思?我没怎么想过,但我认为这是不可能的,尤其是因为Memcache可以在任何时候无理由地刷新所有数据。