将数据库事务放在我们应用程序中的每个服务方法周围会增加开销吗?
我们目前仅在明确/明显需要的情况下使用数据库事务。我最近建议围绕所有服务方法进行交易,但其他一些开发人员提出了一个谨慎的问题:这会增加开销吗?
我的感觉不是——从数据库的角度来看,自动提交与事务相同。但这准确吗?
数据库:MySQL
将数据库事务放在我们应用程序中的每个服务方法周围会增加开销吗?
我们目前仅在明确/明显需要的情况下使用数据库事务。我最近建议围绕所有服务方法进行交易,但其他一些开发人员提出了一个谨慎的问题:这会增加开销吗?
我的感觉不是——从数据库的角度来看,自动提交与事务相同。但这准确吗?
数据库:MySQL
你是对的,使用自动提交,每个语句都包含在事务中。如果您的服务方法正在执行多个 sql 语句,最好将它们包装到一个事务中。查看此答案以获取更多详细信息,这是有关该主题的不错的博客文章。
为了回答您的问题,是的,事务确实会增加性能开销,但在您的特定情况下,您不会注意到差异,因为您已经启用了自动提交,除非您在服务方法中有长时间运行的语句,这将导致表上的锁定时间更长参与交易。如果您只是将多个语句包装在一个事务中,您将获得一个事务(而不是每个单独语句的事务),如此处所指出的(“启用自动提交的会话可以通过显式启动它来执行多语句事务START TRANSACTION 或 BEGIN 语句并以 COMMIT 或 ROLLBACK 语句结束”),您将在服务方法级别实现原子性......
最后,我会选择您的解决方案,如果从在服务方法级别实现原子性的角度来看这是有意义的(我认为您想要实现),但是对性能有 + 和 - 影响,具体取决于您的查询,请求/秒等...
简短的回答是,这取决于您的表格类型。如果您使用默认的 MyISAM,则实际上没有事务,因此对性能应该没有影响。
但无论如何你都应该使用它们。没有交易,就没有工作的划分。如果您升级到 InnoDB 或像 PostgreSQL 这样的真实数据库,无论如何您都希望将这些事务添加到您的服务方法中,因此您不妨现在就养成这种习惯,而这不会花费您任何费用。
此外,您应该已经在使用事务性商店。如果当前服务方法失败,您如何清理?如果您将一些信息写入数据库,然后您的服务方法抛出异常,您如何清除那些不完整或错误的信息?如果您使用事务,则不必这样做——数据库会为您丢弃回滚数据。或者,如果我正在执行一个方法并且另一个请求进来并找到我写一半的数据,你会怎么做?当它去寻找还没有的另一半时,它会爆炸吗?事务数据存储将为您处理此问题:您的事务将彼此隔离,因此其他人无法看到部分写入的事务。
就像所有数据库一样,唯一确定的答案将来自使用真实数据和真实负载进行的测试。无论您怀疑什么,我都建议您始终这样做,因为当涉及到数据库时,当数据很大时会激活不同的代码路径,而当它们不是时会激活不同的代码路径。但我强烈怀疑即使使用 InnoDB 使用事务的成本也不是很高。毕竟,这些系统每天都被大大小小的组织大量使用,这些组织依赖于良好的交易表现。MVCC 增加了很少的开销。好处是巨大的,成本很低——使用它们!
是的,他们可以增加开销。将交易相互隔离所需的额外“簿记”可能变得很重要,尤其是在交易长时间保持开放的情况下。