Fix savepoint boundary semantics and detach/reattach rollback · Issue #191 · eclipse-cdo/cdo · GitHub
Skip to content

Fix savepoint boundary semantics and detach/reattach rollback #191

Closed

Description

@estepper

Problem

CDO savepoints did not reliably preserve their documented point-in-time semantics, especially across multiple savepoints and detach/reattach lifecycle changes.

Several related problems existed:

  • A returned CDOSavepoint was also used as the mutable segment for changes made after that savepoint. As a result, public getAll...() APIs could include changes from later segments instead of representing a stable savepoint boundary.
  • Persistent detach → unchanged reattach → rollback could lose the revision required to restore the original persistent object. This could result in an object with a null revision or lost persistent identity.
  • The same lifecycle problem also affected NEW objects across savepoints. Rollback could fail to restore the original temporary ID, revision, view registration, and new-object registration.
  • Reattach processing could clear the transaction-global dirty flag when only the current segment had become empty, even though older savepoint segments still contained uncommitted changes.
  • Rollback metadata for lifecycle changes had an incorrect lifetime because it partially depended on transaction-wide cleanRevisions.

Fix

The savepoint implementation now explicitly separates:

  • public savepoint boundary semantics, representing the fixed transaction state at setSavepoint() time;
  • internal current-state aggregation, which additionally includes the mutable segment after that boundary.

Internal ...IncludingCurrent() aggregation APIs are used by transaction commit, rollback, query, and active-state processing, while public CDOSavepoint#getAll...() methods remain fixed at their savepoint boundary.

Segment-local lifecycle before-images were introduced for rollback-sensitive object state. A before-image is captured once per object and segment and preserves the state required to restore persistent and NEW objects exactly across detach/reattach sequences.

This restores, where applicable:

  • CDO state
  • persistent or temporary CDO ID
  • revision/baseline revision
  • transaction/view registration
  • new-object registration
  • subsequent object usability

cleanRevisions remains as the transaction-wide persistent baseline registry, but lifecycle rollback no longer depends on it for state that belongs to an individual savepoint segment.

Global dirty-state handling was also corrected so that an empty current segment cannot make the transaction clean while older segments still contain pending changes.

The public/internal savepoint semantics were clarified in the APIs, and an existing test that required active-segment state was migrated to the explicit current-inclusive API.

Result

Savepoints now provide stable point-in-time semantics externally while retaining segmented/delta-based storage internally.

Rollback correctly handles:

  • persistent detach/reattach within one segment;
  • persistent detach/reattach across multiple savepoints;
  • NEW detach/reattach with restoration of the original temporary identity;
  • later continued use of objects and transactions after rollback.

Metadata

Metadata

Assignees

Labels

cdo-coreCDO Model Repository (Core)enhancementNew feature or request

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions