Skip to content

Add opt-in MongoDB multi-document transactions to GORM for MongoDB#15744

Open
codeconsole wants to merge 4 commits into
apache:8.0.xfrom
codeconsole:feat/mongo-server-transactions
Open

Add opt-in MongoDB multi-document transactions to GORM for MongoDB#15744
codeconsole wants to merge 4 commits into
apache:8.0.xfrom
codeconsole:feat/mongo-server-transactions

Conversation

@codeconsole

Copy link
Copy Markdown
Contributor

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:

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.

GORM for MongoDB previously treated a transaction as a client-side flush
boundary: pending writes were batched and flushed on commit, but each write
auto-committed individually and nothing rolled back when a later operation failed.

This adds real server-side transactions backed by a com.mongodb.client.ClientSession.
When grails.mongodb.transactional is enabled (default false), a GORM transaction
starts a ClientSession and MongoDB transaction and every read and write for the
session runs within it, committing or aborting atomically. A new MongoTransaction
drives the commit (retrying on an UnknownTransactionCommitResult) and the abort, and
closes the session afterwards.

The feature is opt-in and degrades gracefully: a standalone topology is detected at
runtime and falls back to the legacy flush-only behavior with a one-time warning.
Identifier generation for native Long ids is intentionally left non-transactional,
mirroring the semantics of database sequences.

@borinquenkid borinquenkid left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @codeconsole,

Please keep an eye on #15678 (GORM: Shared Mapping Registry O(M+N) Scaling), which introduces significant internal structural refactoring to how GormRegistry and MongoDatastore handle tenant routing and fallback resolution.

Since that optimization is targeting 8.0.x-hibernate7, your transaction changes here will be downstream from those modifications. It might be worth checking your diff against those updates to prevent initialization order regressions or multi-tenant signature mismatches when merging into the 8.0 release line.

…ve Long id tests

On a failed commit (or a flush failure during commit), MongoTransaction now explicitly
aborts the server transaction rather than relying on ClientSession.close() to abort it
implicitly. Adds tests covering native Long identifier generation inside a transaction:
ids are generated and persisted on commit, and the document is rolled back on failure
even though the id counter is intentionally not enrolled in the transaction.
…ined

The clientSession field is accessed only on the owning session's thread (per the
AbstractSession single-thread-confinement contract), so it needs no synchronization.
Adds a clarifying comment; no behavior change.
@testlens-app

testlens-app Bot commented Jun 20, 2026

Copy link
Copy Markdown

🚨 TestLens detected 8 failed tests 🚨

Here is what you can do:

  1. Inspect the test failures carefully.
  2. If you are convinced that some of the tests are flaky, you can mute them below.
  3. Finally, trigger a rerun by checking the rerun checkbox.

Test Summary

CI - Groovy Joint Validation Build / build_grails > :grails-data-mongodb-core:test

Test Runs
MongoTransactionSpec > test a REQUIRES_NEW inner transaction commits independently of a rolled back outer transaction
MongoTransactionSpec > test a committed transaction persists all writes atomically
MongoTransactionSpec > test a findOneAndDelete via the MongoEntity API participates in the transaction
MongoTransactionSpec > test a rolled back transaction discards a native Long id entity (id generation is non-transactional)
MongoTransactionSpec > test a rolled back transaction discards all writes on the server
MongoTransactionSpec > test native Long identifier generation works for entities committed in a transaction
MongoTransactionSpec > test read-your-writes within an active transaction
MongoTransactionSpec > test writes across multiple collections roll back together

🏷️ Commit: 9993091
▶️ Tests: 42225 executed
⚪️ Checks: 44/44 completed

Test Failures

MongoTransactionSpec > test a REQUIRES_NEW inner transaction commits independently of a rolled back outer transaction (:grails-data-mongodb-core:test in CI - Groovy Joint Validation Build / build_grails)
com.mongodb.MongoTimeoutException: Timed out while waiting for a server that matches WritableServerSelector. Client view of cluster state is {type=UNKNOWN, servers=[{address=localhost:32805, type=UNKNOWN, state=CONNECTING, exception={com.mongodb.MongoSocketOpenException: Exception opening socket}, caused by {java.net.ConnectException: Connection refused}}]
	at com.mongodb.internal.connection.BaseCluster.logAndThrowTimeoutException(BaseCluster.java:431)
	at com.mongodb.internal.connection.BaseCluster.lambda$selectServer$0(BaseCluster.java:166)
	at com.mongodb.internal.time.Timeout.lambda$onExistsAndExpired$16(Timeout.java:238)
	at com.mongodb.internal.time.Timeout.lambda$run$10(Timeout.java:203)
	at com.mongodb.internal.time.TimePoint.checkedCall(TimePoint.java:100)
	at com.mongodb.internal.time.Timeout.call(Timeout.java:176)
	at com.mongodb.internal.time.Timeout.run(Timeout.java:196)
	at com.mongodb.internal.time.Timeout.onExistsAndExpired(Timeout.java:235)
	at com.mongodb.internal.time.Timeout.onExpired(Timeout.java:228)
	at com.mongodb.internal.connection.BaseCluster.selectServer(BaseCluster.java:165)
	at com.mongodb.internal.connection.SingleServerCluster.selectServer(SingleServerCluster.java:47)
	at com.mongodb.internal.binding.ClusterBinding.getWriteConnectionSource(ClusterBinding.java:91)
	at com.mongodb.client.internal.ClientSessionBinding.getConnectionSource(ClientSessionBinding.java:109)
	at com.mongodb.client.internal.ClientSessionBinding.getWriteConnectionSource(ClientSessionBinding.java:102)
	at com.mongodb.internal.operation.SyncOperationHelper.withSuppliedResource(SyncOperationHelper.java:169)
	at com.mongodb.internal.operation.SyncOperationHelper.withSourceAndConnection(SyncOperationHelper.java:138)
	at com.mongodb.internal.operation.SyncOperationHelper.withConnection(SyncOperationHelper.java:117)
	at com.mongodb.internal.operation.DropDatabaseOperation.execute(DropDatabaseOperation.java:73)
	at com.mongodb.internal.operation.DropDatabaseOperation.execute(DropDatabaseOperation.java:48)
	at com.mongodb.client.internal.MongoClusterImpl$OperationExecutorImpl.execute(MongoClusterImpl.java:472)
	at com.mongodb.client.internal.MongoDatabaseImpl.executeDrop(MongoDatabaseImpl.java:230)
	at com.mongodb.client.internal.MongoDatabaseImpl.drop(MongoDatabaseImpl.java:220)
	at org.grails.datastore.gorm.mongo.transactions.MongoTransactionSpec.setup_closure1(MongoTransactionSpec.groovy:55)
	at org.grails.datastore.gorm.GormStaticApi.withNewSession(GormStaticApi.groovy:1019)
	at org.grails.datastore.gorm.GormEntity$Trait$Helper.withNewSession(GormEntity.groovy:1115)
	at org.grails.datastore.gorm.mongo.transactions.MongoTransactionSpec.setup(MongoTransactionSpec.groovy:54)
MongoTransactionSpec > test a committed transaction persists all writes atomically (:grails-data-mongodb-core:test in CI - Groovy Joint Validation Build / build_grails)
com.mongodb.MongoSocketReadException: Prematurely reached end of stream
	at com.mongodb.internal.connection.SocketStream.read(SocketStream.java:184)
	at com.mongodb.internal.connection.InternalStreamConnection.receiveResponseBuffers(InternalStreamConnection.java:942)
	at com.mongodb.internal.connection.InternalStreamConnection.receiveCommandMessageResponse(InternalStreamConnection.java:567)
	at com.mongodb.internal.connection.InternalStreamConnection.sendAndReceiveInternal(InternalStreamConnection.java:494)
	at com.mongodb.internal.connection.InternalStreamConnection.lambda$sendAndReceive$1(InternalStreamConnection.java:383)
	at com.mongodb.internal.connection.InternalStreamConnection.sendAndReceive(InternalStreamConnection.java:386)
	at com.mongodb.internal.connection.UsageTrackingInternalConnection.sendAndReceive(UsageTrackingInternalConnection.java:111)
	at com.mongodb.internal.connection.DefaultConnectionPool$PooledConnection.sendAndReceive(DefaultConnectionPool.java:757)
	at com.mongodb.internal.connection.CommandProtocolImpl.execute(CommandProtocolImpl.java:60)
	at com.mongodb.internal.connection.DefaultServer$DefaultServerProtocolExecutor.execute(DefaultServer.java:207)
	at com.mongodb.internal.connection.DefaultServerConnection.executeProtocol(DefaultServerConnection.java:112)
	at com.mongodb.internal.connection.DefaultServerConnection.command(DefaultServerConnection.java:82)
	at com.mongodb.internal.connection.DefaultServerConnection.command(DefaultServerConnection.java:74)
	at com.mongodb.internal.connection.DefaultServer$OperationCountTrackingConnection.command(DefaultServer.java:297)
	at com.mongodb.internal.operation.SyncOperationHelper.lambda$executeRetryableWrite$11(SyncOperationHelper.java:285)
	at com.mongodb.internal.operation.SyncOperationHelper.lambda$withSourceAndConnection$1(SyncOperationHelper.java:146)
	at com.mongodb.internal.operation.SyncOperationHelper.withSuppliedResource(SyncOperationHelper.java:177)
	at com.mongodb.internal.operation.SyncOperationHelper.lambda$withSourceAndConnection$2(SyncOperationHelper.java:142)
	at com.mongodb.internal.operation.SyncOperationHelper.withSuppliedResource(SyncOperationHelper.java:177)
	at com.mongodb.internal.operation.SyncOperationHelper.withSourceAndConnection(SyncOperationHelper.java:138)
	at com.mongodb.internal.operation.SyncOperationHelper.lambda$executeRetryableWrite$12(SyncOperationHelper.java:270)
	at com.mongodb.internal.operation.SyncOperationHelper.lambda$decorateWriteWithRetries$13(SyncOperationHelper.java:329)
	at com.mongodb.internal.async.function.RetryingSyncSupplier.get(RetryingSyncSupplier.java:67)
	at com.mongodb.internal.operation.SyncOperationHelper.executeRetryableWrite(SyncOperationHelper.java:297)
	at com.mongodb.internal.operation.BaseFindAndModifyOperation.execute(BaseFindAndModifyOperation.java:81)
	at com.mongodb.client.internal.MongoClusterImpl$OperationExecutorImpl.execute(MongoClusterImpl.java:472)
	at com.mongodb.client.internal.MongoCollectionImpl.executeFindOneAndUpdate(MongoCollectionImpl.java:787)
	at com.mongodb.client.internal.MongoCollectionImpl.findOneAndUpdate(MongoCollectionImpl.java:766)
	at org.grails.datastore.mapping.mongo.engine.MongoCodecEntityPersister.generateIdentifier(MongoCodecEntityPersister.groovy:443)
	at org.grails.datastore.mapping.mongo.engine.MongoCodecEntityPersister.persistEntity(MongoCodecEntityPersister.groovy:226)
	at org.grails.datastore.mapping.mongo.engine.MongoCodecEntityPersister.persistEntity(MongoCodecEntityPersister.groovy:567)
	at org.grails.datastore.mapping.engine.EntityPersister.persist(EntityPersister.java:188)
	at org.grails.datastore.mapping.core.AbstractSession.persist(AbstractSession.java:609)
	at org.grails.datastore.gorm.GormInstanceApi.doSave(GormInstanceApi.groovy:369)
	at org.grails.datastore.gorm.GormInstanceApi.save_closure5(GormInstanceApi.groovy:184)
	at org.grails.datastore.mapping.core.DatastoreUtils.execute(DatastoreUtils.java:335)
	at org.grails.datastore.gorm.AbstractDatastoreApi.execute(AbstractDatastoreApi.groovy:44)
	at org.grails.datastore.gorm.GormInstanceApi.save(GormInstanceApi.groovy:183)
	at org.grails.datastore.gorm.GormInstanceApi.save(GormInstanceApi.groovy:123)
	at org.grails.datastore.gorm.GormEntity$Trait$Helper.save(GormEntity.groovy:110)
	at org.grails.datastore.gorm.mongo.transactions.MongoTransactionSpec.test a committed transaction persists all writes atomically_closure2(MongoTransactionSpec.groovy:70)
	at grails.gorm.transactions.GrailsTransactionTemplate$2.doInTransaction(GrailsTransactionTemplate.groovy:98)
	at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:137)
	at grails.gorm.transactions.GrailsTransactionTemplate.execute(GrailsTransactionTemplate.groovy:95)
	at org.grails.datastore.gorm.GormStaticApi.withTransaction(GormStaticApi.groovy:1009)
	at org.grails.datastore.gorm.GormStaticApi.withTransaction(GormStaticApi.groovy:872)
	at org.grails.datastore.gorm.GormEntity$Trait$Helper.withTransaction(GormEntity.groovy:1024)
	at org.grails.datastore.gorm.mongo.transactions.MongoTransactionSpec.test a committed transaction persists all writes atomically(MongoTransactionSpec.groovy:68)
MongoTransactionSpec > test a findOneAndDelete via the MongoEntity API participates in the transaction (:grails-data-mongodb-core:test in CI - Groovy Joint Validation Build / build_grails)
com.mongodb.MongoTimeoutException: Timed out while waiting for a server that matches WritableServerSelector. Client view of cluster state is {type=UNKNOWN, servers=[{address=localhost:32805, type=UNKNOWN, state=CONNECTING, exception={com.mongodb.MongoSocketOpenException: Exception opening socket}, caused by {java.net.ConnectException: Connection refused}}]
	at com.mongodb.internal.connection.BaseCluster.logAndThrowTimeoutException(BaseCluster.java:431)
	at com.mongodb.internal.connection.BaseCluster.lambda$selectServer$0(BaseCluster.java:166)
	at com.mongodb.internal.time.Timeout.lambda$onExistsAndExpired$16(Timeout.java:238)
	at com.mongodb.internal.time.Timeout.lambda$run$10(Timeout.java:203)
	at com.mongodb.internal.time.TimePoint.checkedCall(TimePoint.java:100)
	at com.mongodb.internal.time.Timeout.call(Timeout.java:176)
	at com.mongodb.internal.time.Timeout.run(Timeout.java:196)
	at com.mongodb.internal.time.Timeout.onExistsAndExpired(Timeout.java:235)
	at com.mongodb.internal.time.Timeout.onExpired(Timeout.java:228)
	at com.mongodb.internal.connection.BaseCluster.selectServer(BaseCluster.java:165)
	at com.mongodb.internal.connection.SingleServerCluster.selectServer(SingleServerCluster.java:47)
	at com.mongodb.internal.binding.ClusterBinding.getWriteConnectionSource(ClusterBinding.java:91)
	at com.mongodb.client.internal.ClientSessionBinding.getConnectionSource(ClientSessionBinding.java:109)
	at com.mongodb.client.internal.ClientSessionBinding.getWriteConnectionSource(ClientSessionBinding.java:102)
	at com.mongodb.internal.operation.SyncOperationHelper.withSuppliedResource(SyncOperationHelper.java:169)
	at com.mongodb.internal.operation.SyncOperationHelper.withSourceAndConnection(SyncOperationHelper.java:138)
	at com.mongodb.internal.operation.SyncOperationHelper.withConnection(SyncOperationHelper.java:117)
	at com.mongodb.internal.operation.DropDatabaseOperation.execute(DropDatabaseOperation.java:73)
	at com.mongodb.internal.operation.DropDatabaseOperation.execute(DropDatabaseOperation.java:48)
	at com.mongodb.client.internal.MongoClusterImpl$OperationExecutorImpl.execute(MongoClusterImpl.java:472)
	at com.mongodb.client.internal.MongoDatabaseImpl.executeDrop(MongoDatabaseImpl.java:230)
	at com.mongodb.client.internal.MongoDatabaseImpl.drop(MongoDatabaseImpl.java:220)
	at org.grails.datastore.gorm.mongo.transactions.MongoTransactionSpec.setup_closure1(MongoTransactionSpec.groovy:55)
	at org.grails.datastore.gorm.GormStaticApi.withNewSession(GormStaticApi.groovy:1019)
	at org.grails.datastore.gorm.GormEntity$Trait$Helper.withNewSession(GormEntity.groovy:1115)
	at org.grails.datastore.gorm.mongo.transactions.MongoTransactionSpec.setup(MongoTransactionSpec.groovy:54)
MongoTransactionSpec > test a rolled back transaction discards a native Long id entity (id generation is non-transactional) (:grails-data-mongodb-core:test in CI - Groovy Joint Validation Build / build_grails)
com.mongodb.MongoTimeoutException: Timed out while waiting for a server that matches WritableServerSelector. Client view of cluster state is {type=UNKNOWN, servers=[{address=localhost:32805, type=UNKNOWN, state=CONNECTING, exception={com.mongodb.MongoSocketOpenException: Exception opening socket}, caused by {java.net.ConnectException: Connection refused}}]
	at com.mongodb.internal.connection.BaseCluster.logAndThrowTimeoutException(BaseCluster.java:431)
	at com.mongodb.internal.connection.BaseCluster.lambda$selectServer$0(BaseCluster.java:166)
	at com.mongodb.internal.time.Timeout.lambda$onExistsAndExpired$16(Timeout.java:238)
	at com.mongodb.internal.time.Timeout.lambda$run$10(Timeout.java:203)
	at com.mongodb.internal.time.TimePoint.checkedCall(TimePoint.java:100)
	at com.mongodb.internal.time.Timeout.call(Timeout.java:176)
	at com.mongodb.internal.time.Timeout.run(Timeout.java:196)
	at com.mongodb.internal.time.Timeout.onExistsAndExpired(Timeout.java:235)
	at com.mongodb.internal.time.Timeout.onExpired(Timeout.java:228)
	at com.mongodb.internal.connection.BaseCluster.selectServer(BaseCluster.java:165)
	at com.mongodb.internal.connection.SingleServerCluster.selectServer(SingleServerCluster.java:47)
	at com.mongodb.internal.binding.ClusterBinding.getWriteConnectionSource(ClusterBinding.java:91)
	at com.mongodb.client.internal.ClientSessionBinding.getConnectionSource(ClientSessionBinding.java:109)
	at com.mongodb.client.internal.ClientSessionBinding.getWriteConnectionSource(ClientSessionBinding.java:102)
	at com.mongodb.internal.operation.SyncOperationHelper.withSuppliedResource(SyncOperationHelper.java:169)
	at com.mongodb.internal.operation.SyncOperationHelper.withSourceAndConnection(SyncOperationHelper.java:138)
	at com.mongodb.internal.operation.SyncOperationHelper.withConnection(SyncOperationHelper.java:117)
	at com.mongodb.internal.operation.DropDatabaseOperation.execute(DropDatabaseOperation.java:73)
	at com.mongodb.internal.operation.DropDatabaseOperation.execute(DropDatabaseOperation.java:48)
	at com.mongodb.client.internal.MongoClusterImpl$OperationExecutorImpl.execute(MongoClusterImpl.java:472)
	at com.mongodb.client.internal.MongoDatabaseImpl.executeDrop(MongoDatabaseImpl.java:230)
	at com.mongodb.client.internal.MongoDatabaseImpl.drop(MongoDatabaseImpl.java:220)
	at org.grails.datastore.gorm.mongo.transactions.MongoTransactionSpec.setup_closure1(MongoTransactionSpec.groovy:55)
	at org.grails.datastore.gorm.GormStaticApi.withNewSession(GormStaticApi.groovy:1019)
	at org.grails.datastore.gorm.GormEntity$Trait$Helper.withNewSession(GormEntity.groovy:1115)
	at org.grails.datastore.gorm.mongo.transactions.MongoTransactionSpec.setup(MongoTransactionSpec.groovy:54)
MongoTransactionSpec > test a rolled back transaction discards all writes on the server (:grails-data-mongodb-core:test in CI - Groovy Joint Validation Build / build_grails)
com.mongodb.MongoTimeoutException: Timed out while waiting for a server that matches WritableServerSelector. Client view of cluster state is {type=UNKNOWN, servers=[{address=localhost:32805, type=UNKNOWN, state=CONNECTING, exception={com.mongodb.MongoSocketOpenException: Exception opening socket}, caused by {java.net.ConnectException: Connection refused}}]
	at com.mongodb.internal.connection.BaseCluster.logAndThrowTimeoutException(BaseCluster.java:431)
	at com.mongodb.internal.connection.BaseCluster.lambda$selectServer$0(BaseCluster.java:166)
	at com.mongodb.internal.time.Timeout.lambda$onExistsAndExpired$16(Timeout.java:238)
	at com.mongodb.internal.time.Timeout.lambda$run$10(Timeout.java:203)
	at com.mongodb.internal.time.TimePoint.checkedCall(TimePoint.java:100)
	at com.mongodb.internal.time.Timeout.call(Timeout.java:176)
	at com.mongodb.internal.time.Timeout.run(Timeout.java:196)
	at com.mongodb.internal.time.Timeout.onExistsAndExpired(Timeout.java:235)
	at com.mongodb.internal.time.Timeout.onExpired(Timeout.java:228)
	at com.mongodb.internal.connection.BaseCluster.selectServer(BaseCluster.java:165)
	at com.mongodb.internal.connection.SingleServerCluster.selectServer(SingleServerCluster.java:47)
	at com.mongodb.internal.binding.ClusterBinding.getWriteConnectionSource(ClusterBinding.java:91)
	at com.mongodb.client.internal.ClientSessionBinding.getConnectionSource(ClientSessionBinding.java:109)
	at com.mongodb.client.internal.ClientSessionBinding.getWriteConnectionSource(ClientSessionBinding.java:102)
	at com.mongodb.internal.operation.SyncOperationHelper.withSuppliedResource(SyncOperationHelper.java:169)
	at com.mongodb.internal.operation.SyncOperationHelper.withSourceAndConnection(SyncOperationHelper.java:138)
	at com.mongodb.internal.operation.SyncOperationHelper.withConnection(SyncOperationHelper.java:117)
	at com.mongodb.internal.operation.DropDatabaseOperation.execute(DropDatabaseOperation.java:73)
	at com.mongodb.internal.operation.DropDatabaseOperation.execute(DropDatabaseOperation.java:48)
	at com.mongodb.client.internal.MongoClusterImpl$OperationExecutorImpl.execute(MongoClusterImpl.java:472)
	at com.mongodb.client.internal.MongoDatabaseImpl.executeDrop(MongoDatabaseImpl.java:230)
	at com.mongodb.client.internal.MongoDatabaseImpl.drop(MongoDatabaseImpl.java:220)
	at org.grails.datastore.gorm.mongo.transactions.MongoTransactionSpec.setup_closure1(MongoTransactionSpec.groovy:55)
	at org.grails.datastore.gorm.GormStaticApi.withNewSession(GormStaticApi.groovy:1019)
	at org.grails.datastore.gorm.GormEntity$Trait$Helper.withNewSession(GormEntity.groovy:1115)
	at org.grails.datastore.gorm.mongo.transactions.MongoTransactionSpec.setup(MongoTransactionSpec.groovy:54)
MongoTransactionSpec > test native Long identifier generation works for entities committed in a transaction (:grails-data-mongodb-core:test in CI - Groovy Joint Validation Build / build_grails)
com.mongodb.MongoTimeoutException: Timed out while waiting for a server that matches WritableServerSelector. Client view of cluster state is {type=UNKNOWN, servers=[{address=localhost:32805, type=UNKNOWN, state=CONNECTING, exception={com.mongodb.MongoSocketOpenException: Exception opening socket}, caused by {java.net.ConnectException: Connection refused}}]
	at com.mongodb.internal.connection.BaseCluster.logAndThrowTimeoutException(BaseCluster.java:431)
	at com.mongodb.internal.connection.BaseCluster.lambda$selectServer$0(BaseCluster.java:166)
	at com.mongodb.internal.time.Timeout.lambda$onExistsAndExpired$16(Timeout.java:238)
	at com.mongodb.internal.time.Timeout.lambda$run$10(Timeout.java:203)
	at com.mongodb.internal.time.TimePoint.checkedCall(TimePoint.java:100)
	at com.mongodb.internal.time.Timeout.call(Timeout.java:176)
	at com.mongodb.internal.time.Timeout.run(Timeout.java:196)
	at com.mongodb.internal.time.Timeout.onExistsAndExpired(Timeout.java:235)
	at com.mongodb.internal.time.Timeout.onExpired(Timeout.java:228)
	at com.mongodb.internal.connection.BaseCluster.selectServer(BaseCluster.java:165)
	at com.mongodb.internal.connection.SingleServerCluster.selectServer(SingleServerCluster.java:47)
	at com.mongodb.internal.binding.ClusterBinding.getWriteConnectionSource(ClusterBinding.java:91)
	at com.mongodb.client.internal.ClientSessionBinding.getConnectionSource(ClientSessionBinding.java:109)
	at com.mongodb.client.internal.ClientSessionBinding.getWriteConnectionSource(ClientSessionBinding.java:102)
	at com.mongodb.internal.operation.SyncOperationHelper.withSuppliedResource(SyncOperationHelper.java:169)
	at com.mongodb.internal.operation.SyncOperationHelper.withSourceAndConnection(SyncOperationHelper.java:138)
	at com.mongodb.internal.operation.SyncOperationHelper.withConnection(SyncOperationHelper.java:117)
	at com.mongodb.internal.operation.DropDatabaseOperation.execute(DropDatabaseOperation.java:73)
	at com.mongodb.internal.operation.DropDatabaseOperation.execute(DropDatabaseOperation.java:48)
	at com.mongodb.client.internal.MongoClusterImpl$OperationExecutorImpl.execute(MongoClusterImpl.java:472)
	at com.mongodb.client.internal.MongoDatabaseImpl.executeDrop(MongoDatabaseImpl.java:230)
	at com.mongodb.client.internal.MongoDatabaseImpl.drop(MongoDatabaseImpl.java:220)
	at org.grails.datastore.gorm.mongo.transactions.MongoTransactionSpec.setup_closure1(MongoTransactionSpec.groovy:55)
	at org.grails.datastore.gorm.GormStaticApi.withNewSession(GormStaticApi.groovy:1019)
	at org.grails.datastore.gorm.GormEntity$Trait$Helper.withNewSession(GormEntity.groovy:1115)
	at org.grails.datastore.gorm.mongo.transactions.MongoTransactionSpec.setup(MongoTransactionSpec.groovy:54)
MongoTransactionSpec > test read-your-writes within an active transaction (:grails-data-mongodb-core:test in CI - Groovy Joint Validation Build / build_grails)
com.mongodb.MongoTimeoutException: Timed out while waiting for a server that matches WritableServerSelector. Client view of cluster state is {type=UNKNOWN, servers=[{address=localhost:32805, type=UNKNOWN, state=CONNECTING, exception={com.mongodb.MongoSocketOpenException: Exception opening socket}, caused by {java.net.ConnectException: Connection refused}}]
	at com.mongodb.internal.connection.BaseCluster.logAndThrowTimeoutException(BaseCluster.java:431)
	at com.mongodb.internal.connection.BaseCluster.lambda$selectServer$0(BaseCluster.java:166)
	at com.mongodb.internal.time.Timeout.lambda$onExistsAndExpired$16(Timeout.java:238)
	at com.mongodb.internal.time.Timeout.lambda$run$10(Timeout.java:203)
	at com.mongodb.internal.time.TimePoint.checkedCall(TimePoint.java:100)
	at com.mongodb.internal.time.Timeout.call(Timeout.java:176)
	at com.mongodb.internal.time.Timeout.run(Timeout.java:196)
	at com.mongodb.internal.time.Timeout.onExistsAndExpired(Timeout.java:235)
	at com.mongodb.internal.time.Timeout.onExpired(Timeout.java:228)
	at com.mongodb.internal.connection.BaseCluster.selectServer(BaseCluster.java:165)
	at com.mongodb.internal.connection.SingleServerCluster.selectServer(SingleServerCluster.java:47)
	at com.mongodb.internal.binding.ClusterBinding.getWriteConnectionSource(ClusterBinding.java:91)
	at com.mongodb.client.internal.ClientSessionBinding.getConnectionSource(ClientSessionBinding.java:109)
	at com.mongodb.client.internal.ClientSessionBinding.getWriteConnectionSource(ClientSessionBinding.java:102)
	at com.mongodb.internal.operation.SyncOperationHelper.withSuppliedResource(SyncOperationHelper.java:169)
	at com.mongodb.internal.operation.SyncOperationHelper.withSourceAndConnection(SyncOperationHelper.java:138)
	at com.mongodb.internal.operation.SyncOperationHelper.withConnection(SyncOperationHelper.java:117)
	at com.mongodb.internal.operation.DropDatabaseOperation.execute(DropDatabaseOperation.java:73)
	at com.mongodb.internal.operation.DropDatabaseOperation.execute(DropDatabaseOperation.java:48)
	at com.mongodb.client.internal.MongoClusterImpl$OperationExecutorImpl.execute(MongoClusterImpl.java:472)
	at com.mongodb.client.internal.MongoDatabaseImpl.executeDrop(MongoDatabaseImpl.java:230)
	at com.mongodb.client.internal.MongoDatabaseImpl.drop(MongoDatabaseImpl.java:220)
	at org.grails.datastore.gorm.mongo.transactions.MongoTransactionSpec.setup_closure1(MongoTransactionSpec.groovy:55)
	at org.grails.datastore.gorm.GormStaticApi.withNewSession(GormStaticApi.groovy:1019)
	at org.grails.datastore.gorm.GormEntity$Trait$Helper.withNewSession(GormEntity.groovy:1115)
	at org.grails.datastore.gorm.mongo.transactions.MongoTransactionSpec.setup(MongoTransactionSpec.groovy:54)
MongoTransactionSpec > test writes across multiple collections roll back together (:grails-data-mongodb-core:test in CI - Groovy Joint Validation Build / build_grails)
com.mongodb.MongoTimeoutException: Timed out while waiting for a server that matches WritableServerSelector. Client view of cluster state is {type=UNKNOWN, servers=[{address=localhost:32805, type=UNKNOWN, state=CONNECTING, exception={com.mongodb.MongoSocketOpenException: Exception opening socket}, caused by {java.net.ConnectException: Connection refused}}]
	at com.mongodb.internal.connection.BaseCluster.logAndThrowTimeoutException(BaseCluster.java:431)
	at com.mongodb.internal.connection.BaseCluster.lambda$selectServer$0(BaseCluster.java:166)
	at com.mongodb.internal.time.Timeout.lambda$onExistsAndExpired$16(Timeout.java:238)
	at com.mongodb.internal.time.Timeout.lambda$run$10(Timeout.java:203)
	at com.mongodb.internal.time.TimePoint.checkedCall(TimePoint.java:100)
	at com.mongodb.internal.time.Timeout.call(Timeout.java:176)
	at com.mongodb.internal.time.Timeout.run(Timeout.java:196)
	at com.mongodb.internal.time.Timeout.onExistsAndExpired(Timeout.java:235)
	at com.mongodb.internal.time.Timeout.onExpired(Timeout.java:228)
	at com.mongodb.internal.connection.BaseCluster.selectServer(BaseCluster.java:165)
	at com.mongodb.internal.connection.SingleServerCluster.selectServer(SingleServerCluster.java:47)
	at com.mongodb.internal.binding.ClusterBinding.getWriteConnectionSource(ClusterBinding.java:91)
	at com.mongodb.client.internal.ClientSessionBinding.getConnectionSource(ClientSessionBinding.java:109)
	at com.mongodb.client.internal.ClientSessionBinding.getWriteConnectionSource(ClientSessionBinding.java:102)
	at com.mongodb.internal.operation.SyncOperationHelper.withSuppliedResource(SyncOperationHelper.java:169)
	at com.mongodb.internal.operation.SyncOperationHelper.withSourceAndConnection(SyncOperationHelper.java:138)
	at com.mongodb.internal.operation.SyncOperationHelper.withConnection(SyncOperationHelper.java:117)
	at com.mongodb.internal.operation.DropDatabaseOperation.execute(DropDatabaseOperation.java:73)
	at com.mongodb.internal.operation.DropDatabaseOperation.execute(DropDatabaseOperation.java:48)
	at com.mongodb.client.internal.MongoClusterImpl$OperationExecutorImpl.execute(MongoClusterImpl.java:472)
	at com.mongodb.client.internal.MongoDatabaseImpl.executeDrop(MongoDatabaseImpl.java:230)
	at com.mongodb.client.internal.MongoDatabaseImpl.drop(MongoDatabaseImpl.java:220)
	at org.grails.datastore.gorm.mongo.transactions.MongoTransactionSpec.setup_closure1(MongoTransactionSpec.groovy:55)
	at org.grails.datastore.gorm.GormStaticApi.withNewSession(GormStaticApi.groovy:1019)
	at org.grails.datastore.gorm.GormEntity$Trait$Helper.withNewSession(GormEntity.groovy:1115)
	at org.grails.datastore.gorm.mongo.transactions.MongoTransactionSpec.setup(MongoTransactionSpec.groovy:54)

Muted Tests

Select tests to mute in this pull request:

  • MongoTransactionSpec > test a REQUIRES_NEW inner transaction commits independently of a rolled back outer transaction
  • MongoTransactionSpec > test a committed transaction persists all writes atomically
  • MongoTransactionSpec > test a findOneAndDelete via the MongoEntity API participates in the transaction
  • MongoTransactionSpec > test a rolled back transaction discards a native Long id entity (id generation is non-transactional)
  • MongoTransactionSpec > test a rolled back transaction discards all writes on the server
  • MongoTransactionSpec > test native Long identifier generation works for entities committed in a transaction
  • MongoTransactionSpec > test read-your-writes within an active transaction
  • MongoTransactionSpec > test writes across multiple collections roll back together

Reuse successful test results:

  • ♻️ Only rerun the tests that failed or were muted before

Click the checkbox to trigger a rerun:

  • Rerun jobs

Learn more about TestLens at testlens.app.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

2 participants