JDO
  1. JDO
  2. JDO-589

Allow makePersistent and deletePersistent outside a transaction

    Details

    • Type: New Feature New Feature
    • Status: Open
    • Priority: Major Major
    • Resolution: Unresolved
    • Affects Version/s: JDO 2 maintenance release 1 (2.1)
    • Fix Version/s: JDO 3.2
    • Component/s: api, specification, tck
    • Labels:
      None

      Description

      JPA allows users to call makePersistent outside a transaction, and then when beginning and committing a transaction, the instances are made persistent.

      This is similar to nontransactional dirty in which the managed instances can be modified outside a transaction and then the changes committed within a transaction.

      From the JPA spec, "When an EntityManager with an extended persistence context is used, the persist, remove, merge, and refresh operations may be called regardless of whether a transaction is active. The effects of these operations will be committed to the database when the extended persistence context is enlisted in a transaction and the transaction commits."

      This behavior should not be the default behavior (for backward compatibility reasons if not the principle of least surprise) so it should be under control of a PersistenceManager and PersistenceManagerFactory flag, perhaps NontransactionalNew.

        Issue Links

          Activity

          Hide
          Craig L Russell added a comment -

          I'd prefer the second option: adding a new property AutoCommit, with
          void setAutoCommit(boolean)
          boolean getAutoCommit()

          Autocommit true, NontransactionalWrite true

          When setting this combination, the cache must not have any dirty objects, and a transaction must not be active. Any write will immediately commit a new transaction.

          Autocommit true, NontransactionalWrite false

          Any write will immediately commit a new transaction.

          Autocommit false, NontransactionalWrite true

          Any makePersistent or deletePersistent or object modification will make the cached objects dirty and will be committed the next time the user begins and commits a transaction. This is the same behavior as today.

          Autocommit false, NontransactionalWrite false

          No makePersistent or deletePersistent or object modification outside a transaction. This is the same behavior as today.

          Show
          Craig L Russell added a comment - I'd prefer the second option: adding a new property AutoCommit, with void setAutoCommit(boolean) boolean getAutoCommit() Autocommit true, NontransactionalWrite true When setting this combination, the cache must not have any dirty objects, and a transaction must not be active. Any write will immediately commit a new transaction. Autocommit true, NontransactionalWrite false Any write will immediately commit a new transaction. Autocommit false, NontransactionalWrite true Any makePersistent or deletePersistent or object modification will make the cached objects dirty and will be committed the next time the user begins and commits a transaction. This is the same behavior as today. Autocommit false, NontransactionalWrite false No makePersistent or deletePersistent or object modification outside a transaction. This is the same behavior as today.
          Hide
          Andy Jefferson added a comment - - edited

          One further option for allowing both semantics :
          Deprecate [get|set]nontransactionalWrite methods and add the following
          void setNontransactionalWriteMode(WriteMode);
          WriteMode getNontransactionalWriteMode();
          public enum WriteMode

          { NONE, ATOMIC, DELAY_UNTIL_COMMIT }

          though from backwards binary compatibility reasons this would not be the simplest.

          Just adding
          void setNontransactionalWriteAutoCommit(boolean)
          boolean getNontransactionalWriteAutoCommit()
          would be simplest.

          Show
          Andy Jefferson added a comment - - edited One further option for allowing both semantics : Deprecate [get|set] nontransactionalWrite methods and add the following void setNontransactionalWriteMode(WriteMode); WriteMode getNontransactionalWriteMode(); public enum WriteMode { NONE, ATOMIC, DELAY_UNTIL_COMMIT } though from backwards binary compatibility reasons this would not be the simplest. Just adding void setNontransactionalWriteAutoCommit(boolean) boolean getNontransactionalWriteAutoCommit() would be simplest.
          Hide
          Craig L Russell added a comment -

          We could simply allow the NonTransactionalWrite flag to affect makePersistent and deletePersistent. This would be a slightly incompatible change; we would no longer throw an exception if a transaction were not in progress.

          But it might not matter.

          Show
          Craig L Russell added a comment - We could simply allow the NonTransactionalWrite flag to affect makePersistent and deletePersistent. This would be a slightly incompatible change; we would no longer throw an exception if a transaction were not in progress. But it might not matter.
          Hide
          Craig L Russell added a comment -

          Here is a proposal for handling both semantics.

          Users could choose either NontransactionalWrite, Autocommit, or neither.

          With NontransactionalWrite true: makePersistent and deletePersistent outside of a transaction would mark the objects as dirty and they would be committed in a subsequent transaction.

          With Autocommit true: makePersistent would start a transaction, implement the persistence by reachability algorithm, and commit the transaction; similarly deletePersistent would start a transaction, delete the object, and commit the transaction.

          With neither true: current behavior.

          With both true: throw an exception when one of the flags is set while the other is set.

          Show
          Craig L Russell added a comment - Here is a proposal for handling both semantics. Users could choose either NontransactionalWrite, Autocommit, or neither. With NontransactionalWrite true: makePersistent and deletePersistent outside of a transaction would mark the objects as dirty and they would be committed in a subsequent transaction. With Autocommit true: makePersistent would start a transaction, implement the persistence by reachability algorithm, and commit the transaction; similarly deletePersistent would start a transaction, delete the object, and commit the transaction. With neither true: current behavior. With both true: throw an exception when one of the flags is set while the other is set.
          Hide
          Craig L Russell added a comment -

          This JIRA specifies an extended persistence context similar to JPA.

          But from what I've seen of NoSQL datastores perhaps auto-commit is a better model. Auto-commit would mean that makePersistent and deletePersistent if called outside a transaction with auto-commit flag turned on, become atomic operations.

          Do we need both semantics?

          Show
          Craig L Russell added a comment - This JIRA specifies an extended persistence context similar to JPA. But from what I've seen of NoSQL datastores perhaps auto-commit is a better model. Auto-commit would mean that makePersistent and deletePersistent if called outside a transaction with auto-commit flag turned on, become atomic operations. Do we need both semantics?
          Hide
          Andy Jefferson added a comment -

          Presumably this means simply that the user can select if they have atomic nontransactional writes (whether persist, delete or update) or whether they want them leaving til the next transaction. What if they select the latter and the PM is closed? do they just get lost like in some popular ORM?

          DataNucleus provides atomic persists/deletes (not updates yet) by default, and allowing them to go to the next transaction when enabled. When a PM is closed and there are outstanding updates then these are committed before completing the close.

          Show
          Andy Jefferson added a comment - Presumably this means simply that the user can select if they have atomic nontransactional writes (whether persist, delete or update) or whether they want them leaving til the next transaction. What if they select the latter and the PM is closed? do they just get lost like in some popular ORM? DataNucleus provides atomic persists/deletes (not updates yet) by default, and allowing them to go to the next transaction when enabled. When a PM is closed and there are outstanding updates then these are committed before completing the close.
          Hide
          Matthew T. Adams added a comment -

          Time to play name that constant! How about NontransactionalPersist or NontransactionalMakePersistent?

          Show
          Matthew T. Adams added a comment - Time to play name that constant! How about NontransactionalPersist or NontransactionalMakePersistent?

            People

            • Assignee:
              Unassigned
              Reporter:
              Craig L Russell
            • Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated:

                Development