【问题标题】:How atomic are SQL transactions really in MySQL?MySQL 中的 SQL 事务到底有多原子?
【发布时间】:2014-02-26 06:22:18
【问题描述】:

我想知道——如果我有一个 SQL 事务,在一个语句中我执行选择查询,然后在后面的语句中执行更新查询,是否可以保证两者之间的外部因素没有任何改变?

  • 所以我在事务中选择了一些行 ⟵

  • 另一个过程更改事务之外的行 ⟵

  • 比我想做的更新⟵在事务中

那么这会发生吗?我知道总事务要么发生,要么不发生,但是 1 个事务中的所有单个语句是否也作为 1 个原子单元执行,在两个不同的语句之间什么都不会发生?或者是通过设置手动表锁来确保数据库被锁定在两个语句之间的唯一方法?

顺便说一句,这个问题是关于这个的:我将钱从一个用户(买方)转移到另一个用户(卖方)。但是,买方在下订单时已经存入了资金。现在他可以随时取消这个买单。然后我会把存入的钱还给他。所以现在可能发生我正在将存款从买家转移到卖家的过程中,而买家取消了他的订单,我把他的钱还给了他。所以现在钱给了买方,也给了卖方。这需要一些高级别的隔离,对吧?

【问题讨论】:

  • 酸中的A有一个非常具体的含义。这与您使用它的方式不同。你的问题是关于隔离的。
  • 哦,好吧。好吧,我对这些东西很陌生,所以请原谅:p 无论如何,你有什么想法可以作为这个问题的答案吗?
  • SQL 标准保证如果您在 SERIALIZABLE 隔离(默认)下运行,那么您的事务将不会看到任何其他事务的任何影响。如果您以较低的隔离级别运行,您将不再受到很好的保护。那么,第二个问题是“MySQL 在该领域对 SQL 标准的遵守情况如何?”这不是很清楚。例如,如果您使用 ISAM 存储,您可能无法获得与使用 InnoDB 一样好的保护。在这种详细程度,我听从比我更了解 MySQL 的人的意见。

标签: mysql sql transactions


【解决方案1】:

这取决于事务隔离级别。 我曾经使用过的所有数据库的默认隔离级别都是已提交读,并且此级别允许查看其他已提交事务所做的更改。 相反,串行或快照隔离级别将当前事务与其他事务隔离,但它的扩展性不如已提交读。 您可以在所有现代数据库上更改每个事务或全局的隔离级别,但我不建议在没有充分理由的情况下这样做,Read Committed 对于典型用例来说是一个很好的隔离,因为它不需要读取锁定,串行隔离使用重锁定以使事务串行而不是并发,并且它可能无法针对典型用例进行扩展。

【讨论】:

  • 好的,谢谢。我刚读到这个:en.wikipedia.org/wiki/Isolation_(database_systems)。看来我确实需要 Serializable 级别,因为如果我理解正确,这是完全排除幻读的唯一级别?
  • 是的,但是如果您在某些特定用例中需要它,我建议更改每个事务的默认级别,全局设置为“串行”会杀死并发。例如“SET TRANSACTION ...”或“ALTER SESSION ...”
  • 我认为您可以随时更改应用程序中的 SQL 语句顺序以避免串行事务执行级别
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-08
  • 1970-01-01
  • 2018-12-09
  • 1970-01-01
  • 2017-07-07
相关资源
最近更新 更多