codeconsole opened a new pull request, #15744:
URL: https://github.com/apache/grails-core/pull/15744

   ## What
   
   Adds **opt-in MongoDB multi-document transactions** to GORM for MongoDB.
   
   Previously GORM for MongoDB never used a `com.mongodb.client.ClientSession`: 
every driver write was issued session-less and auto-committed, so a GORM 
transaction was only a client-side flush boundary — writes already flushed 
within it were **not** rolled back on failure (no server-side atomicity).
   
   With `grails.mongodb.transactional = true`, a GORM transaction now starts 
and drives a real `ClientSession` transaction, so all reads and writes commit 
or roll back atomically:
   
   ```groovy
   Person.withTransaction {
       new Person(name: "Fred").save()
       new Person(name: "Wilma").save()
       // both commit together, or neither if an exception is thrown
   }
   ```
   
   ## How
   
   - New `MongoTransaction` (replaces the flush-only `SessionOnlyTransaction` 
when enabled): `commit()` flushes then `commitTransaction()` (with bounded 
retry on `UnknownTransactionCommitResult`), `rollback()` aborts; both close the 
session. On commit failure the GORM session cache is cleared.
   - `AbstractMongoSession` holds the active `ClientSession`, starts it in 
`beginTransactionInternal()`, and routes every read/write through small helpers 
that pass the session when a transaction is active and stay session-less 
otherwise.
   - The session is threaded through both session engines, both persisters, 
`MongoQuery`, and the `MongoStaticApi`/`MongoEntity` surface.
   - Core `DatastoreTransactionManager` is unchanged — it already orchestrates 
flush/commit/rollback; this just supplies a `Transaction` that drives a server 
transaction.
   
   ## Opt-in and fallback
   
   - Default is **off** (`grails.mongodb.transactional` defaults to `false`) — 
no behavior change for existing apps.
   - Requires a replica set or sharded cluster. If a standalone topology is 
detected, the feature is disabled with a one-time warning and GORM falls back 
to the legacy flush behavior.
   
   ## Boundaries
   
   - Identifier generation (the native `Long` counter) is intentionally left 
non-transactional, mirroring database sequence semantics.
   - Like GORM's transaction manager generally, a single flat transaction 
(`PROPAGATION_REQUIRED`) is supported; `REQUIRES_NEW`/`NESTED` are not.
   
   ## Tests
   
   - `MongoTransactionSpec` — commit persists multiple docs; rollback discards 
them on the server; read-your-writes within a transaction; cross-collection 
atomic rollback; `findOneAndDelete` participates in the transaction; nested 
GORM `REQUIRES_NEW`.
   - `MongoTransactionDisabledSpec` — default-off keeps the legacy flush 
behavior.
   
   Targets `8.0.x`. Independent of #15743; this is also the prerequisite for a 
follow-up Spring Data MongoDB interop module.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to