使用 API/函数调用或采用 Cron Job 方法 - 查询处理事务 - 您将如何处理它?
我正在使用 PHP 和 MySQL 启动一个新项目,大致如下:
每分钟我都会从不同用户的 API 获取待办事务列表。
示例:
user1 send $1 to user2
userx send $2 to usera
userw send $0.50 to user2
etc..
假设用户 1 想要将 $1 发送给用户 2。 有两种可能,成功或者因为资金不足或者用户名拼错而失败。 如果不成功,我会向用户发送一条消息。
我现在面临几个选项:
选项 1
创建一个包含需要处理的事务的数据库表,并使用每分钟处理它们的 cronjob。 这里的风险是脚本运行时可能会出现错误或超时,而其他事务仍会在数据库表中显示“正在进行”。 所以我需要第二个脚本来根据时间戳进行检查。
选项 2
创建一个 API 或函数,在我收到每笔交易后调用该 API 或函数并给我带来响应。 然后我可以调用另一个 API 或函数来处理该响应或继续下一个事务。 但是,我仍然必须将它们放入数据库表中,因为如果脚本停止执行,我不能冒丢失它们的风险。 因此它的工作方式如下:将所有事务放入数据库表中 - 启动事务 - 完成事务后从表中删除 - 启动事务 2。
这两个选项都有缺陷,因为您不知道事务列表有多长。 如果它很长,PHP 绝对不是长时间运行的最佳选择 - 使用将超时设置为零是有风险的。 我正在寻求创建一个可以通过 PHP 扩展的解决方案。 所以我正在考虑选项 3。
选项 3(最佳解决方案?)
使用 API 返回 10 笔交易。
在数据库中设置一个标志来表示它们被发送到脚本,并设置时间戳来表示它们何时发送
PHP 脚本从 API 检索 10 个事务 - 处理 10 个事务。
事务完成后 - 将其从该表中删除并将其复制到已完成的事务表中。
让 cronjob 脚本每 3 分钟检查一次 timeent 是否大于 X 分钟(基于 10 个事务的执行时间上限)。 如果它更大 - 将它们设置为不发送 - 这样它们就可以再次发送出去。
正如你所看到的,我写下了我对此的整个思考过程,并正在寻找输入。 肯定有一些我错过的东西。 另请注意,这些不是真正的金融交易 - 这只是我可以用来澄清这一点的最佳元前。
I am starting a new project with PHP and MySQL which is roughly the following:
Every minute I get a list of to-do transactions from an API from different users.
Example:
user1 send $1 to user2
userx send $2 to usera
userw send $0.50 to user2
etc..
Lets say user1 wants to send $1 to user2. There are two posibilities, it's succesful or it's unsuccessful because there are insufficient funds or the user spelled the username wrong. If it's unsuccesfull I send out a message to the user.
I am now facing several options:
Option 1
Create a database table with transactions that need to be processed and use a cronjob that processes them every minute. The risk here is that the script could run against an error or a timeout and the other transactions would still show In Progress in the database table. So I would need a second script to check that against a timestamp.
Option 2
Create an API or Function which gets called for each transaction after I receive them and brings me a response. From which then I can call another API or Function to deal with that response or move on to the next transaction. However I would still have to put them in a database table since I can't risk losing them if the script stops executing. So it would work as follow: put all transactions in database table - start transaction - when finished transaction delete from table - start transaction 2.
Both options are flawed because you don't know how long the list of transactions will be. If it's long PHP is definitely not optimal to run for a long time - using set timeout to zero is risky. I am looking to create a solution that will scale with PHP. So I was thinking about an Option 3.
Option 3 (Optimal solution?)
Use an API to return 10 transactions.
In database set a flag to say they are sent to a script and timestamp to say when they were sent
PHP script retreives 10 transactions from API - handles 10 transactions.
Once transaction completed - delete it from this table and copy it to completed transaction table.
Have a cronjob script check every 3 minutes if timesent is greater then X minutes (based on an upper bound of the execution time of 10 transactions). If it is greater - set them to not sent - so they can be sent out again.
As you can see I wrote down my whole thought process on this and am looking for input. There's bound to be stuff that I missed. Also please realize that these are not real financial transactions - it's just the best metafore I could use to make it clear.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您想使用当前技术堆栈的最小差异来做到这一点,那么您就走在正确的道路上。 本质上,您正在重新创建一个简单的 MQ 或作业服务器。
作业/任务/事务队列所需的最低功能是:
您可能还需要
如果您决定并行处理 cron 作业,您将需要跟踪哪个实例该脚本有一项工作需要处理,特别是当您开始大批量操作时。 (如果你这样做,你需要注意确保任何给定的事务快速完成,或者你可以有效地停止单个慢速作业后面的所有作业)
无论是从 API 获取还是直接从数据库获取一个是 6 个,另一个是 6 个。
If you want to do it using the bare minimum variance from your current technology stack you're on the right track. Essentially you're re-creating a bare bones MQ or job server.
Minimum features you need for job/task/transaction queue are:
You're also probably going to want
If you decide to parallelize your processing cron job, you'll want to track which instance of the script has a job out for processing, especially if you start operating on large batches. (and if you do that, you're going to want to watch to make sure any given transaction finishes fast, or you can effectively stall all the jobs behind a single slow job)
Whether you fetch it from an API or straight from the database is 6 of one, half a dozen of the other.
我建议在收到该交易的请求时处理每笔交易。
IE Bob 单击“汇款”按钮将 20 美元发送给 Alice。 我会调用一个函数来处理此事务,并向他们显示“事务成功”或“出现问题..”消息。
如果事务处理需要很长时间,您可以通过 AJAX 完成它,在服务器端完成处理时向他们显示一个漂亮的进度条,上面写着“正在处理..”,然后将它们重定向到您的站点。 com/transactions.php?result=success&id=$id 或
yoursite.com/transactions.php?result=failure&id=$id
I would suggest processing each transaction when the request for that transaction is received.
I.E Bob clicks a 'Send money' button to send $20 to Alice. I would call a function to handle this transaction, and show them a 'Transaction successful' or 'There was a problem..' message right there.
If a transaction processing will take long, you could have it done via AJAX, showing them a nice progress bar saying 'Processing..' while the processing is being done on the server side, and then either redirect them to
yoursite.com/transactions.php?result=success&id=$id
oryoursite.com/transactions.php?result=failure&id=$id