0

I need to implement optimistic on my google datastore kind.

I am using my own key rather than a generated one and using the google datastore node.js api.

As insert, update, upsert all seem to de delegated to the save() method ( as per the docs) I can easily end up overwriting data if I am not careful.

So basically I have to try a 'read' before doing any insert or update and then after that I have to be careful to 'overwrite' the correct properties before calling save().

If I manage to read and then properly 'overwrite' the correct fields I still need to be sure that I am the latest writer to that entity so I would need some sort of optimistic locking with a version/timestamp field. I have read somewhere that this is in built in but its not so explicit in the official docs at https://googlecloudplatform.github.io/google-cloud-node/#/docs/datastore/0.7.1/datastore?method=insert

can someone shed some light on this ?

Dan McGrath
  • 41,220
  • 11
  • 99
  • 130
1977
  • 2,580
  • 6
  • 26
  • 37

1 Answers1

1

Cloud Datastore transactions use optimistic locking.

Process A:

  • T1 -> Start Transaction
  • T2 -> Read Entity X
  • T4 -> Write Entity X
  • T5 -> Commit Transaction

Process B:

  • T3 -> Write Entity X

In the above scenario, since Cloud Datastore uses optimistic locking, Process A's transaction will fail since entity X was written between the Read and the Write.

Note: insert, upsert, update all map to save, but have the method explicitly passed along via the optional method string so the correct type of write is performed: source

Dan McGrath
  • 41,220
  • 11
  • 99
  • 130
  • so it has its own some sort of internal version/timestamp that it uses for the optimistic lock ?. And just to be sure - I should just call save() as insert/upsert/update all map to that anyway ? – 1977 Mar 18 '17 at 14:17
  • 1) Yes, it has it's own internal version number. 2) No quite. As I mentioning, it isn't just mapping to save, but also passing along a parameter that tells save what type of operation to perform. If you call save() directly, you need to ensure to set that parameter as appropriate (so it's easy just to call the correct insert/update/upsert method instead) – Dan McGrath Mar 18 '17 at 17:23
  • btw when i obtain a transaction via ds.transaction() and then proceed to do my work inside a transaction.run() block.. then is it allowable to mix multiple transaction.update's and transaction.insert's on different kinds before finally executing transaction.commit() – 1977 Mar 23 '17 at 03:47
  • Yes, kinds make no difference. If you perform inserts/updates across entity-groups (different root entities) it is called a "Cross Entity Group (XG) transaction". There is a limit to 25 different Entity Groups in an XG transaction. – Dan McGrath Mar 23 '17 at 04:46