#247·500lines

Transaction bug in functional db, the 'ts' field will be incorrect if execute more than one operations in a single transaction?

Author: mlmhlCreated Feb 25, 2017Updated Jul 10, 2018

@yoavrubin

The functional db project is really cool, and I learned a lot from it. After reading it, I have a doubt about the Transaction section. I'm not familiar with Clojure, if I have a wrong understanding, please forgive me, thank you very much.

In the transact-on-db function, each operations will be executed on the initial-db and finally generated an updated database named transacted, and then the newest layer in transacted will be appended to the initial-db as the newest layer. I think there is a bug in the last process if more than one operations need to be executed in an transaction. Consider the following example:

  1. The initial-db has two layers, the first layer is empty(ts is 0), and the second one has only one entity e with an attribute named a, and a's value is v1, ts is 1.
  2. Execute two update operations in a transaction: the first one will update a to v2 and the second one will update a to v3. The first operation will generate a new layer, in which a's value is v2 and ts is 2, prev-ts is 1. The second operation will generate a new layer too, in which a's value is v3, ts is 3, prev-ts is 2.
  3. After above two operations, transact-on-db will append the layer generated by second operation to initial-db's layers, now the initial-db has three layers, the first one's ts is 0, the second one's ts is 1, but the third one's ts is 3, and a's prev-ts is 2 in the third layer. At this time, if we invoke the evolution-of function on initial-db, we will fall into an infinite loop.

The above example is just one possible error, if we execute more than two update operations in a single transaction and then invoke evolution-of, we will fall into a 'layer not found' error.