TE
科技回声
首页24小时热榜最新最佳问答展示工作
GitHubTwitter
首页

科技回声

基于 Next.js 构建的科技新闻平台,提供全球科技新闻和讨论内容。

GitHubTwitter

首页

首页最新最佳问答展示工作

资源链接

HackerNews API原版 HackerNewsNext.js

© 2025 科技回声. 版权所有。

Hermitage: Testing the “I” in ACID

110 点作者 martinkl超过 10 年前

10 条评论

Animats超过 10 年前
A key concept here is that real databases have transactions, there&#x27;s some concurrency between transactions, and that in the more efficient modes, transactions can deadlock, fail, and be rolled back.<p>In MySQL, a statement within a transaction can return &quot;ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction&quot;. This can be forced by the following sequence of events. (This assumes an InnoDB table in Repeatable Read mode.)<p><pre><code> Process A does a START TRANSACTION. Process B does a START TRANSACTION. Process A does a SELECT which reads row X. Process B does a SELECT which reads row X. Process A does an UPDATE which writes row X. Process B does an UPDATE which writes row X. - Deadlock error. </code></pre> Process B gets a report that the transaction failed, and everything done in B&#x27;s transaction is rolled back. The entire transaction has to be retried. Transactions are atomic if they commit, but can fail in a deadlock situation.<p>A SELECT does lock parts of the database. &quot;Repeatable read&quot; means that if you read the same data item twice within the same transaction, you get the same result, even if someone else is changing the data. This requires locking. If you try to update the data in conflict with another process, you&#x27;ll get a deadlock error, but if you COMMIT a select-only transaction, you won&#x27;t. You do have to COMMIT select-only transactions, or you&#x27;ll fill memory with locks and stall out updates.<p>Ref: <a href="http://dev.mysql.com/doc/refman/5.1/en/innodb-lock-modes.html" rel="nofollow">http:&#x2F;&#x2F;dev.mysql.com&#x2F;doc&#x2F;refman&#x2F;5.1&#x2F;en&#x2F;innodb-lock-modes.htm...</a>
评论 #8659409 未加载
jeffdavis超过 10 年前
&quot;...able withdraw more money than they had in their account...Most so-called ACID databases — for example Postgres, MySQL, Oracle or MS SQL Server — would not have prevented this race condition in their default configuration.&quot;<p>The author didn&#x27;t really show that this was true. He obviously understands isolation well, so I would tend to believe him, but it would be nice to see an example.<p>In a simple case (not sure that it matches the exchange&#x27;s case), postgresql in any configuration will prevent this problem:<p><pre><code> CREATE TABLE account( id int8, balance numeric, check (balance &gt;= 0) ); </code></pre> No matter what concurrent activity you have going on, it&#x27;s impossible (as far as I know) to end up seeing a balance less than 0. That&#x27;s actually true in <i>any</i> isolation mode that postgres supports (read committed, snapshot isolation, and truly serializable).<p>Does someone have a counterexample, or more details about the case at the exchange that would not be solved by postgres?<p>I&#x27;d also like to point out that the postgres&#x27;s implementation of true serializability performs quite well and there isn&#x27;t much of a cost to using it over snapshot isolation.
评论 #8661235 未加载
评论 #8661283 未加载
评论 #8661189 未加载
jrullmann超过 10 年前
Very cool - would love to see tests of FoundationDB!<p>FYI I&#x27;m an engineer at FDB, happy to help.
评论 #8658987 未加载
wpietri超过 10 年前
Interesting! One minor quibble:<p>&gt; The idea of isolation is that we want our database to be able to process several transactions at the same time (otherwise it would be terribly slow)<p>Not necessarily true. Things like Prevayler and LMAX provide isolation by processing transactions one at a time, and they&#x27;re very fast. They manage this by keeping everything relevant hot in RAM. LMAX, for example, can do 6 million TPS for a financial trading platform. You can read Martin Fowler writing about LMAX here: <a href="http://martinfowler.com/articles/lmax.html" rel="nofollow">http:&#x2F;&#x2F;martinfowler.com&#x2F;articles&#x2F;lmax.html</a>
a-priori超过 10 年前
In case it&#x27;s interesting to people, here&#x27;s a blog post I made earlier this year on the topic of what exactly transaction isolation means:<p><a href="http://www.michaelmelanson.net/2014/03/20/transactions/" rel="nofollow">http:&#x2F;&#x2F;www.michaelmelanson.net&#x2F;2014&#x2F;03&#x2F;20&#x2F;transactions&#x2F;</a>
评论 #8660189 未加载
fintler超过 10 年前
I wonder what approach you could use for global safe timestamp snapshot transaction checking.<p><a href="https://static.googleusercontent.com/media/research.google.com/en/us/pubs/archive/41344.pdf" rel="nofollow">https:&#x2F;&#x2F;static.googleusercontent.com&#x2F;media&#x2F;research.google.c...</a>
jeffdavis超过 10 年前
I strongly rebut the following claim, which is central to the article:<p>&quot;Internet commenters, in their infinite wisdom, were quick to point out that if you’re dealing with money, you had better use an ACID database. But there was a major flaw in their argument. Most so-called ACID databases — for example Postgres, MySQL, Oracle or MS SQL Server — would not have prevented this race condition in their default configuration.&quot;<p>I hesitate because I don&#x27;t really understand the details of the situation the exchange faced. But, going by the linked references here:<p><a href="https://bitcointalk.org/index.php?topic=499580" rel="nofollow">https:&#x2F;&#x2F;bitcointalk.org&#x2F;index.php?topic=499580</a> <a href="http://www.reddit.com/r/Bitcoin/comments/1wtbiu/how_i_stole_roughly_100_btc_from_an_exchange_and/" rel="nofollow">http:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;Bitcoin&#x2F;comments&#x2F;1wtbiu&#x2F;how_i_stole_...</a><p>it appears that the pattern in question, if translated very unnaturally to SQL, is something like:<p><pre><code> CREATE TABLE account(id int8, balance numeric); ... BEGIN; SELECT balance FROM account WHERE id = 123; -- application sees 100, subtracts 90, sees that -- it&#x27;s still positive and does: UPDATE account SET balance = 10 WHERE id = 123; COMMIT; </code></pre> Technically speaking, running that in postgres in the default configuration (read committed) is prone to a race, and you&#x27;d need to use repeatable read or serializable mode to protect you.<p>But that&#x27;s ridiculous. Anyone using SQL would instead do:<p><pre><code> CREATE TABLE account(id int8, balance numeric, check(balance &gt;= 0)); ... UPDATE account SET balance = balance - 90 WHERE id = 123; </code></pre> And that is <i>not</i> prone to a race. Try it in any version of postgres, in any configuration. You can&#x27;t get double withdrawls (where only one takes effect), and you can&#x27;t get it to go below zero.<p>So, the author is <i>technically</i> right: (a) if you translate the NoSQL-isms into SQL in an unnatural way; <i>and</i> (b) don&#x27;t bother to use SERIALIZABLE mode, which costs very little in most situations.<p>I agree with the author that isolation is tricky, and developers should not be expected to understand the nuances. And I applaud the development of a testing framework to really understand the various kinds of isolation and how they apply to different products. But the example is a bad one, because it actually does work just fine in postgres, and probably many other systems.
评论 #8661783 未加载
评论 #8664294 未加载
talles超过 10 年前
There&#x27;s been so much drugs articles in HN lately that I literally expected some LSD story here...
jackhulsom超过 10 年前
Nice ! Very interesting.
amixofpersons超过 10 年前
An interesting read.