NoSQL Storage Systems Never Violate ACID. Never? Well, Hardly Ever!
Everybody agrees that the new “NoSQL” storage systems “aren’t ACID”, or “don’t have transactions”. This is true <i>in a sense</i>, but without knowing the sense, it doesn’t tell you much.
In one sense, they <i>do</i> have transactions that are limited to having one operation per transaction. One operation could mean reading, writing, incrementing, or doubling the value associated with a particular key. For example, look at an “insert” operation in a key/value store. An operations acts on only one data object. Are these single-operation transactions ACID? Let’s check each criterion:
A means “atomic”: either all the operations happen, or none of them happens. Well, there’s only one operation. The key-value store <i>does</i> guarantee that either the insert happens, or it doesn’t. So the transaction atomic.
C means “consistent”. In relational database systems, people use this to mean that various interesting consistency guarantees are maintained. But here, we don’t have to worry about such things as referential integrity, since there are no references to have integrity; that is, there are no foreign keys. So it’s consistent.
I means “isolated”: concurrency is never seen by the application. The system behaves as if each operation happened at a particular, distinct moment in time. The key-value stores all make this guarantee.
D means “durable”: before the application is told that the transaction has been completed successfully (i.e. committed), any side-effects it does are in stable storage so that if a node stops (such as a crash of a process or a whole node) won’t lose the results of the side-effects. Here, a transaction is only one operation, but that doesn’t change anything: the system does provide “durability”. (Some systems might cheat by not actually forcing data to stable storage, but we’re not talking about those.)
So it appears to be ACID! OK, something has <i>got</i> to be wrong here, right?
Right. Where I tried to pull the wool over your eyes is the definition of “C”. “C” doesn’t just mean conforming to the databases integrity constraints. It means that the system returns the correct answer! That is, response to any operation is consistent with some state that the database could be in. There’s more than one such state when there are concurrent operations going on, which might be ordered in more than one way, depending on how the concurrency system works. So it’s clearer to think of “C” as meaning “correct”. (In the famous Gilbert and Lynch paper that “proves the CAP theorem”, that’s what they mean by “C”.)
The “NoSQL” storage systems are guaranteed return the correct answer <i>only</i>if there are no partitions in the network. But if there are (or were, e.g. at write time) partitions, they can return things like “two replicas say the value is X, but another replica says that the answer is Y”, and the application has to try to make sense of and cope with that. That is <i>not</i> “C”. This is usually called “eventually consistency”: if the partitions were to eventually heal and the system deferred accepting new operations until all the in-progress operations finished, and something went over the whole database to fix up any inconsistencies that happened during writes, then the system would become fully consistent, and would be behave correctly until the next partition.
that there are at least two nodes that cannot send messages between each other. It’s important to know that if a node in your your system is down, that’s considered a partition: it’s as if this node were disconnected from the network.
The “NoSQL” systems are ACID, as long as you accept that a transaction can only perform one operation, in the sense that the only thing that gets in the way of being ACID is when there are network partitions and the system is called upon to perform operations while the partition is still there.
“Partition” is a somewhat slippery concept that I will examine in an upcoming separate essay. But the basic ides is that a it means that there are at least two nodes that cannot send messages between them. It’s important to know that if a node in your your system is down, that’s considered a partition: it’s as if this node were disconnected from the network.
This also shows that the name “NoSQL” doesn’t explain everything that’s important about these systems. But you can’t pack a whole lot into a short, punchy name, so I’m not really complaining. ( do the same thing with the names of my blog essays; <i>mea culpa<i>. You just have to keep in mind that the lack of SQL is not the only important thing.