How does HLC hybrid logical clock solve Linearizability and Serializability in distributed transaction?

109 Views Asked by At

My understanding why distributed transaction need synchronized clock is the following

true time = 100ms
node A local time = 100ms
node B local time = 0ms

the following transaction will run into conflicted sequenece

transactionA arrive nodeA at (true time 100ms, A time 100ms, B time 0ms)
transactionA commit by nodeA at (true time 110ms, A time 110ms, B time 10ms)
nodeB gets transactionA replicated at (true time 111ms, A time 111ms, B time 11ms) BUT with timestamp (110ms)
transactionB arrive nodeB at (true time 120ms, A time 120ms, B time 20ms)
transactionB is commit by nodeB at (true time 130ms, A time 130ms, B time 30ms)

now there is a conflict in transaction time between transactionA and transactionB

transactionA commit time = 110ms (local of A)
transactionB commit time = 30ms (local of B)

transaction A should be processed before transaction B , but because node B lag node A by 100ms transactionB is now considered to be processed before transactionA

How does HLC solve this problem? From my understanding HLC just have two component, time and a number that monotonically increase, when you have a conflict you just compare the time and the number, and time is compare first

  @Override
  public int compareTo(HybridTimestamp other) {
      if (this.wallClockTime == other.wallClockTime) {
          return Integer.compare(this.ticks, other.ticks);
      }
      return Long.compare(this.wallClockTime, other.wallClockTime);
  }

So you will still reach the same problem because time is compared first?

1

There are 1 best solutions below

0
On

Sharing this as a community wiki for the benefit of others

As mentioned by @John Hanley

You cannot have two transactions that affect each other. Starting a transaction creates locks. Starting another dependant transaction would have to wait for the previous locks to be released. That feature is common to all SQL databases. You are trying to create scenarios that were solved decades ago. cloud.google.com/spanner/docs/transactions#locking

If the two transactions do not affect each other, it does not matter when they are committed. If they affect each other, you can only begin one transaction, the other one must wait. The scenario you are inventing cannot happen. I admire that you want to understand Spanner in-depth, but first, you must understand basic SQL database design. Google has pretty good documentation for the basics plus there are good books to read.