[odb-users] PostgreSQL C++ ORM (ODB): What's the scope of database lock in transactions? Can transactions fail?

Sam lists1 at afach.de
Thu Jul 19 13:12:20 EDT 2018


   Hi guys,
   I'm new to database development, but been doing C++ for a long time.
   I'm using PostgreSQL with ODB. I understand that transactions
   introduce the concept of atomicity in database to modify multiple
   entries/tables and ensure consistency (even in read-modify-write
   operations over multiple tables). But what I don't understand is how a
   transaction can always succeed given these (apparently) impossible
   circumstances.  I'm writing a program that may use hundreds of threads
   to access the same database, and I'm wondering whether I have to
   assume the possibility of failed transactions.
   First, let's establish that ODB allows to do transactions from
   multiple threads, but only 1 transaction per thread. I can always
   imagine situations like this one:
   `F1()` in thread 1:
   1. Begin transcation
   2. Load row X
   3. Load row Y in another table
   4. Execute some C++ code on X and Y
   5. Modify rows X and Y and conclude the transaction
   `F2()` in thread 2:
   1. Begin transaction
   2. Load row Y
   3. Execute C++ code on row Y
   4. Load row X
   5. Execute C++ code on rows X and Y
   6. Modify both X and Y and conclude the transaction
   Assuming PostgreSQL doesn't do global locks (which [1]seems to be the
   case), what will happen if `F1()` is between 2 and 3, and `F2()` is
   between 2 and 3?
   The puzzle to me here is that ODB never knows that row Y is needed in
   `F1()` next, and doesn't know that X is needed by `F2()` next. So now,
   it can either load row Y for `F1()`, which will make `F2()` fail,
   because Y will be modified, or load X for `F2()`, which will make
   `F1()` fail. Let's also remember that ODB is just a library, so it
   cannot simply roll back `F1()` (although it can roll back the
   database), as it cannot control the flow of the program. Doesn't this
   assert that transactions can fail due to atomicity?
   If transactions can fail, what's the correct way to deal with this?
   Infinite loops trying again and again until a successful attempt
   passes? The ODB manual [2]never seems to be discussing a failure
   situation, except when the program fails
   Can I assume that a transaction can never fail because of concurrency,
   but can only block? What are the correct assumptions when dealing with
   transactions?

   Best regards,
   Sam

References

   1. https://www.2ndquadrant.com/en/postgresql/postgresql-vs-mysql/
   2. https://www.codesynthesis.com/products/odb/doc/manual.xhtml#3.5


More information about the odb-users mailing list