I'm curious how does FoundationDB handle a situation in which there are multiple transactions trying to update the same key?
If one client executes this transaction:
db.run((Transaction tr) -> {
tr.set(Tuple.from("key").pack(), Tuple.from("valueA").pack());
return null;
});
While another client executes a conflicting transaction:
db.run((Transaction tr) -> {
tr.set(Tuple.from("key").pack(), Tuple.from("valueB").pack());
return null;
});
What will happen inside FoundationDB to resolve that conflict?
Recently I've been exploring and testing FoundationDB (I guess everyone is playing with it at the moment) and as a part of my explorations I've made some simple tests. One of them should answer your questions:
So, below is an example (hope you wouldn't mind Scala):
So, this thing allows you to start several threads writing into the same object. There is some unirequired code left from other experiments, ignore it (or use for your own experiments).
This code spawns your threads, then each thread reads a tuple of five longs, like
(0,1,0,0,0)
from key("OBJ", 100)
, then increments value corresponding to thread number then writes it back and increments one of the volatile counters.And these are my observations:
println(s"again: $v1, v0=$v0, 0=${next(0)}")
So, essentially, when a conflict occurs FoundationDB clients are trying to commit the transactions until they succeed. You may find more details in this chapter of the docs. Then look at the architecture overview diagram.
Also note that your transactions are just functions. Hopefully - idempotent functions.
And you should know that in many cases you may avoid conflicts by using atomic operations on your value.
Hope this answers your question.
I would advice you to read all the official docs through so you may find many intersting things there including how the database developers consider CAP theorem, nice examples of cool distributed data structures and many other technical details and interesting things.