Browse Source

DATAMONGO-535 - Fixed broken MongoDBUtils resource synchronization.

We now make sure we really re-use the database instance bound to the thread avoiding duplicate lookups of Mongo.getDb(…). This doesn't seem to gain a big performance benefit anymore as the Mongo instance caches the DB instances internally anyway.
pull/12/head
Oliver Gierke 13 years ago
parent
commit
f1289c46e6
  1. 15
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoDbUtils.java
  2. 29
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoDbUtilsUnitTests.java

15
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoDbUtils.java

@ -79,14 +79,12 @@ public abstract class MongoDbUtils { @@ -79,14 +79,12 @@ public abstract class MongoDbUtils {
DbHolder dbHolder = (DbHolder) TransactionSynchronizationManager.getResource(mongo);
if (dbHolder != null && !dbHolder.isEmpty()) {
// Do we have a populated holder and TX sync active?
if (dbHolder != null && !dbHolder.isEmpty() && TransactionSynchronizationManager.isSynchronizationActive()) {
DB db = null;
if (TransactionSynchronizationManager.isSynchronizationActive() && dbHolder.doesNotHoldNonDefaultDB()) {
db = dbHolder.getDB(databaseName);
DB db = dbHolder.getDB(databaseName);
// DB found but not yet synchronized
if (db != null && !dbHolder.isSynchronizedWithTransaction()) {
LOGGER.debug("Registering Spring transaction synchronization for existing MongoDB {}.", databaseName);
@ -94,13 +92,13 @@ public abstract class MongoDbUtils { @@ -94,13 +92,13 @@ public abstract class MongoDbUtils {
TransactionSynchronizationManager.registerSynchronization(new MongoSynchronization(dbHolder, mongo));
dbHolder.setSynchronizedWithTransaction(true);
}
}
if (db != null) {
return db;
}
}
// Lookup fresh database instance
LOGGER.debug("Getting Mongo Database name=[{}]", databaseName);
DB db = mongo.getDB(databaseName);
@ -117,8 +115,7 @@ public abstract class MongoDbUtils { @@ -117,8 +115,7 @@ public abstract class MongoDbUtils {
}
}
// Use same Session for further Mongo actions within the transaction.
// Thread object will get removed by synchronization at transaction completion.
// TX sync active, bind new database to thread
if (TransactionSynchronizationManager.isSynchronizationActive()) {
LOGGER.debug("Registering Spring transaction synchronization for MongoDB instance {}.", databaseName);

29
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoDbUtilsUnitTests.java

@ -17,10 +17,17 @@ package org.springframework.data.mongodb.core; @@ -17,10 +17,17 @@ package org.springframework.data.mongodb.core;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import static org.mockito.Matchers.*;
import static org.mockito.Mockito.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.runners.MockitoJUnitRunner;
import org.mockito.stubbing.Answer;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import com.mongodb.DB;
@ -31,13 +38,21 @@ import com.mongodb.Mongo; @@ -31,13 +38,21 @@ import com.mongodb.Mongo;
*
* @author Oliver Gierke
*/
@RunWith(MockitoJUnitRunner.class)
public class MongoDbUtilsUnitTests {
@Mock
Mongo mongo;
@Before
public void setUp() throws Exception {
this.mongo = new Mongo();
when(mongo.getDB(anyString())).then(new Answer<DB>() {
public DB answer(InvocationOnMock invocation) throws Throwable {
return mock(DB.class);
}
});
TransactionSynchronizationManager.initSynchronization();
}
@ -55,11 +70,15 @@ public class MongoDbUtilsUnitTests { @@ -55,11 +70,15 @@ public class MongoDbUtilsUnitTests {
public void returnsNewInstanceForDifferentDatabaseName() {
DB first = MongoDbUtils.getDB(mongo, "first");
assertThat(first, is(notNullValue()));
assertThat(MongoDbUtils.getDB(mongo, "first"), is(first));
DB second = MongoDbUtils.getDB(mongo, "second");
assertThat(second, is(not(first)));
assertThat(MongoDbUtils.getDB(mongo, "second"), is(second));
}
@Test
public void returnsSameInstanceForSameDatabaseName() {
DB first = MongoDbUtils.getDB(mongo, "first");
assertThat(first, is(notNullValue()));
assertThat(MongoDbUtils.getDB(mongo, "first"), is(sameInstance(first)));
}
}

Loading…
Cancel
Save