我想创建一个用于以类似事务的方式处理发票的界面。
数据库包含一张发票表和一张invoice_lines表,发票表中包含结算信息,invoice_lines表包含发票的订单项。该网站是一组脚本,允许添加,修改和删除发票及其相应的行。
我遇到的问题是,我希望数据库的ACID属性能够反映在Web应用程序中。
如果我正在编写桌面应用程序,它将始终保持与MySQL数据库的连接,允许我在编辑的开头和结尾简单地使用BEGIN TRANSACTION和COMMIT。
根据我的理解,你不能在一个PHP页面上进行交易,而在另一个页面上进行COMMIT,因为页面之间的连接是关闭的。
有没有办法在没有扩展的情况下实现这一目标?根据我的发现,只有SQL Relay执行此操作(但它是一个扩展名)。
答案 0 :(得分:7)
您不希望长时间运行事务,因为这会限制并发性。 http://en.wikipedia.org/wiki/Command_pattern
答案 1 :(得分:4)
此类处理的网络翻译是使用会话数据或页面本身存储的数据。通常所做的是,在每个网页完成之后,数据被存储在会话中(或页面本身中)以及所有页面已经完成的点(通过数据输入)和“处理”(点击或“保存”按钮,数据被转换为数据库表格并保存 - 即使你提到的数据的关系方面。有很多方法可以做到这一点,但我想说大多数开发人员都有类似于我提到的架构(使用会话数据或页面中的状态)来满足你所说的。
你会在不同的架构上得到很多建议,但我可以说Zend框架(http://framework.zend.com)和Doctrine(http://www.doctrine-project.org/)的使用使这个仙女变得容易,因为Zend提供了大量的MVC架构和会话管理以及Doctrine提供了您正在寻找的基本CRUD(创建,检索,更新,删除) - 以及所有其他方面(唯一性,提交,回滚等)。保持连接对mysql开放可能会导致超时和缺少可用的连接。
答案 2 :(得分:2)
数据库事务并非真正用于此目的 - 如果您确实使用它们,则可能会遇到其他问题。
但您也不能使用它们,因为每个页面请求都使用自己的连接(可能),因此无法与任何其他页面共享事务。
在用户编辑发票时,在其他地方保留对发票的修改,然后在她点击保存时应用它们;你可以在一个交易中做最后的申请步骤(尽管这个步骤很短暂)。
长期交易通常很糟糕。
答案 3 :(得分:1)
解决方案不是在GET阶段打开交易。在“保存”按钮触发POST期间,执行事务的所有方面 - BEGIN TRANSACTION,processing和COMMIT-all。
答案 4 :(得分:0)
持久连接可以帮助您: http://php.net/manual/en/features.persistent-connections.php
另一个是使用时 交易,交易块会 也转到下一个脚本 如果脚本使用该连接 执行在交易之前结束 块确实。
但我建议你找另一种解决问题的方法。 例如:创建缓存表。 当您需要“提交”时,将记录从缓存表传输到“真实”表。
答案 5 :(得分:0)
尽管有一些很好的答案,我认为对你的问题找到了一些好的回答,我也被困在了。我认为最好的方法是使用像Doctrine(O / R映射)这样的框架,这种方法以某种方式实现。 Here你有我正在谈论的内容的链接。