Skip to content

Commit e914b73

Browse files
committed
Polishing.
Introduce Lock utility for easier lock handling.
1 parent 5e7cbe3 commit e914b73

File tree

6 files changed

+209
-112
lines changed

6 files changed

+209
-112
lines changed

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

+37-36
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,9 @@
1818
import java.util.Collection;
1919
import java.util.List;
2020
import java.util.Set;
21-
import java.util.concurrent.atomic.AtomicReference;
22-
import java.util.concurrent.locks.Lock;
2321
import java.util.concurrent.locks.ReentrantLock;
2422
import java.util.function.Consumer;
2523
import java.util.function.Supplier;
26-
import java.util.function.UnaryOperator;
2724
import java.util.stream.Stream;
2825

2926
import org.bson.Document;
@@ -50,6 +47,7 @@
5047
import org.springframework.data.mongodb.core.query.Query;
5148
import org.springframework.data.mongodb.core.query.Update;
5249
import org.springframework.data.mongodb.core.query.UpdateDefinition;
50+
import org.springframework.data.mongodb.util.Lock;
5351
import org.springframework.lang.Nullable;
5452
import org.springframework.util.Assert;
5553
import org.springframework.util.ClassUtils;
@@ -192,20 +190,18 @@ default SessionScoped withSession(Supplier<ClientSession> sessionProvider) {
192190

193191
return new SessionScoped() {
194192

195-
private final Lock lock = new ReentrantLock();
193+
private final Lock lock = Lock.of(new ReentrantLock());
196194
private @Nullable ClientSession session;
197195

198196
@Override
199197
public <T> T execute(SessionCallback<T> action, Consumer<ClientSession> onComplete) {
200198

201-
lock.lock();
202-
try {
199+
lock.executeWithoutResult(() -> {
200+
203201
if (session == null) {
204202
session = sessionProvider.get();
205203
}
206-
} finally {
207-
lock.unlock();
208-
}
204+
});
209205

210206
try {
211207
return action.doInSession(MongoOperations.this.withSession(session));
@@ -950,8 +946,8 @@ default <T> List<T> findDistinct(Query query, String field, String collection, C
950946
* Triggers <a href="https://docs.mongodb.org/manual/reference/method/db.collection.findAndModify/">findAndModify </a>
951947
* to apply provided {@link Update} on documents matching {@link Criteria} of given {@link Query}.
952948
*
953-
* @param query the {@link Query} class that specifies the {@link Criteria} used to find a document and also an optional
954-
* fields specification. Must not be {@literal null}.
949+
* @param query the {@link Query} class that specifies the {@link Criteria} used to find a document and also an
950+
* optional fields specification. Must not be {@literal null}.
955951
* @param update the {@link UpdateDefinition} to apply on matching documents. Must not be {@literal null}.
956952
* @param entityClass the parametrized type. Must not be {@literal null}.
957953
* @return the converted object that was updated before it was updated or {@literal null}, if not found.
@@ -966,8 +962,8 @@ default <T> List<T> findDistinct(Query query, String field, String collection, C
966962
* Triggers <a href="https://docs.mongodb.org/manual/reference/method/db.collection.findAndModify/">findAndModify </a>
967963
* to apply provided {@link Update} on documents matching {@link Criteria} of given {@link Query}.
968964
*
969-
* @param query the {@link Query} class that specifies the {@link Criteria} used to find a document and also an optional
970-
* fields specification. Must not be {@literal null}.
965+
* @param query the {@link Query} class that specifies the {@link Criteria} used to find a document and also an
966+
* optional fields specification. Must not be {@literal null}.
971967
* @param update the {@link UpdateDefinition} to apply on matching documents. Must not be {@literal null}.
972968
* @param entityClass the parametrized type. Must not be {@literal null}.
973969
* @param collectionName the collection to query. Must not be {@literal null}.
@@ -984,8 +980,8 @@ default <T> List<T> findDistinct(Query query, String field, String collection, C
984980
* to apply provided {@link Update} on documents matching {@link Criteria} of given {@link Query} taking
985981
* {@link FindAndModifyOptions} into account.
986982
*
987-
* @param query the {@link Query} class that specifies the {@link Criteria} used to find a document and also an optional
988-
* fields specification.
983+
* @param query the {@link Query} class that specifies the {@link Criteria} used to find a document and also an
984+
* optional fields specification.
989985
* @param update the {@link UpdateDefinition} to apply on matching documents.
990986
* @param options the {@link FindAndModifyOptions} holding additional information.
991987
* @param entityClass the parametrized type.
@@ -1004,8 +1000,8 @@ default <T> List<T> findDistinct(Query query, String field, String collection, C
10041000
* to apply provided {@link Update} on documents matching {@link Criteria} of given {@link Query} taking
10051001
* {@link FindAndModifyOptions} into account.
10061002
*
1007-
* @param query the {@link Query} class that specifies the {@link Criteria} used to find a document and also an optional
1008-
* fields specification. Must not be {@literal null}.
1003+
* @param query the {@link Query} class that specifies the {@link Criteria} used to find a document and also an
1004+
* optional fields specification. Must not be {@literal null}.
10091005
* @param update the {@link UpdateDefinition} to apply on matching documents. Must not be {@literal null}.
10101006
* @param options the {@link FindAndModifyOptions} holding additional information. Must not be {@literal null}.
10111007
* @param entityClass the parametrized type. Must not be {@literal null}.
@@ -1030,8 +1026,8 @@ <T> T findAndModify(Query query, UpdateDefinition update, FindAndModifyOptions o
10301026
* Options are defaulted to {@link FindAndReplaceOptions#empty()}. <br />
10311027
* <strong>NOTE:</strong> The replacement entity must not hold an {@literal id}.
10321028
*
1033-
* @param query the {@link Query} class that specifies the {@link Criteria} used to find a document and also an optional
1034-
* fields specification. Must not be {@literal null}.
1029+
* @param query the {@link Query} class that specifies the {@link Criteria} used to find a document and also an
1030+
* optional fields specification. Must not be {@literal null}.
10351031
* @param replacement the replacement document. Must not be {@literal null}.
10361032
* @return the converted object that was updated or {@literal null}, if not found.
10371033
* @throws org.springframework.data.mapping.MappingException if the collection name cannot be
@@ -1051,8 +1047,8 @@ default <T> T findAndReplace(Query query, T replacement) {
10511047
* Options are defaulted to {@link FindAndReplaceOptions#empty()}. <br />
10521048
* <strong>NOTE:</strong> The replacement entity must not hold an {@literal id}.
10531049
*
1054-
* @param query the {@link Query} class that specifies the {@link Criteria} used to find a document and also an optional
1055-
* fields specification. Must not be {@literal null}.
1050+
* @param query the {@link Query} class that specifies the {@link Criteria} used to find a document and also an
1051+
* optional fields specification. Must not be {@literal null}.
10561052
* @param replacement the replacement document. Must not be {@literal null}.
10571053
* @param collectionName the collection to query. Must not be {@literal null}.
10581054
* @return the converted object that was updated or {@literal null}, if not found.
@@ -1070,8 +1066,8 @@ default <T> T findAndReplace(Query query, T replacement, String collectionName)
10701066
* taking {@link FindAndReplaceOptions} into account.<br />
10711067
* <strong>NOTE:</strong> The replacement entity must not hold an {@literal id}.
10721068
*
1073-
* @param query the {@link Query} class that specifies the {@link Criteria} used to find a document and also an optional
1074-
* fields specification. Must not be {@literal null}.
1069+
* @param query the {@link Query} class that specifies the {@link Criteria} used to find a document and also an
1070+
* optional fields specification. Must not be {@literal null}.
10751071
* @param replacement the replacement document. Must not be {@literal null}.
10761072
* @param options the {@link FindAndModifyOptions} holding additional information. Must not be {@literal null}.
10771073
* @return the converted object that was updated or {@literal null}, if not found. Depending on the value of
@@ -1093,8 +1089,8 @@ default <T> T findAndReplace(Query query, T replacement, FindAndReplaceOptions o
10931089
* taking {@link FindAndReplaceOptions} into account.<br />
10941090
* <strong>NOTE:</strong> The replacement entity must not hold an {@literal id}.
10951091
*
1096-
* @param query the {@link Query} class that specifies the {@link Criteria} used to find a document and also an optional
1097-
* fields specification. Must not be {@literal null}.
1092+
* @param query the {@link Query} class that specifies the {@link Criteria} used to find a document and also an
1093+
* optional fields specification. Must not be {@literal null}.
10981094
* @param replacement the replacement document. Must not be {@literal null}.
10991095
* @param options the {@link FindAndModifyOptions} holding additional information. Must not be {@literal null}.
11001096
* @return the converted object that was updated or {@literal null}, if not found. Depending on the value of
@@ -1116,8 +1112,8 @@ default <T> T findAndReplace(Query query, T replacement, FindAndReplaceOptions o
11161112
* taking {@link FindAndReplaceOptions} into account.<br />
11171113
* <strong>NOTE:</strong> The replacement entity must not hold an {@literal id}.
11181114
*
1119-
* @param query the {@link Query} class that specifies the {@link Criteria} used to find a document and also an optional
1120-
* fields specification. Must not be {@literal null}.
1115+
* @param query the {@link Query} class that specifies the {@link Criteria} used to find a document and also an
1116+
* optional fields specification. Must not be {@literal null}.
11211117
* @param replacement the replacement document. Must not be {@literal null}.
11221118
* @param options the {@link FindAndModifyOptions} holding additional information. Must not be {@literal null}.
11231119
* @param entityType the parametrized type. Must not be {@literal null}.
@@ -1141,8 +1137,8 @@ default <T> T findAndReplace(Query query, T replacement, FindAndReplaceOptions o
11411137
* taking {@link FindAndReplaceOptions} into account.<br />
11421138
* <strong>NOTE:</strong> The replacement entity must not hold an {@literal id}.
11431139
*
1144-
* @param query the {@link Query} class that specifies the {@link Criteria} used to find a document and also an optional
1145-
* fields specification. Must not be {@literal null}.
1140+
* @param query the {@link Query} class that specifies the {@link Criteria} used to find a document and also an
1141+
* optional fields specification. Must not be {@literal null}.
11461142
* @param replacement the replacement document. Must not be {@literal null}.
11471143
* @param options the {@link FindAndModifyOptions} holding additional information. Must not be {@literal null}.
11481144
* @param entityType the type used for mapping the {@link Query} to domain type fields and deriving the collection
@@ -1171,8 +1167,8 @@ default <S, T> T findAndReplace(Query query, S replacement, FindAndReplaceOption
11711167
* taking {@link FindAndReplaceOptions} into account.<br />
11721168
* <strong>NOTE:</strong> The replacement entity must not hold an {@literal id}.
11731169
*
1174-
* @param query the {@link Query} class that specifies the {@link Criteria} used to find a document and also an optional
1175-
* fields specification. Must not be {@literal null}.
1170+
* @param query the {@link Query} class that specifies the {@link Criteria} used to find a document and also an
1171+
* optional fields specification. Must not be {@literal null}.
11761172
* @param replacement the replacement document. Must not be {@literal null}.
11771173
* @param options the {@link FindAndModifyOptions} holding additional information. Must not be {@literal null}.
11781174
* @param entityType the type used for mapping the {@link Query} to domain type fields. Must not be {@literal null}.
@@ -1680,7 +1676,8 @@ default long exactCount(Query query, String collectionName) {
16801676
* acknowledged} remove operation was successful or not.
16811677
*
16821678
* @param object must not be {@literal null}.
1683-
* @param collectionName name of the collection where the documents will be removed from, must not be {@literal null} or empty.
1679+
* @param collectionName name of the collection where the documents will be removed from, must not be {@literal null}
1680+
* or empty.
16841681
* @return the {@link DeleteResult} which lets you access the results of the previous delete.
16851682
*/
16861683
DeleteResult remove(Object object, String collectionName);
@@ -1704,7 +1701,8 @@ default long exactCount(Query query, String collectionName) {
17041701
*
17051702
* @param query the query document that specifies the criteria used to remove a document.
17061703
* @param entityClass class of the pojo to be operated on. Can be {@literal null}.
1707-
* @param collectionName name of the collection where the documents will be removed from, must not be {@literal null} or empty.
1704+
* @param collectionName name of the collection where the documents will be removed from, must not be {@literal null}
1705+
* or empty.
17081706
* @return the {@link DeleteResult} which lets you access the results of the previous delete.
17091707
* @throws IllegalArgumentException when {@literal query}, {@literal entityClass} or {@literal collectionName} is
17101708
* {@literal null}.
@@ -1718,7 +1716,8 @@ default long exactCount(Query query, String collectionName) {
17181716
* information. Use {@link #remove(Query, Class, String)} to get full type specific support.
17191717
*
17201718
* @param query the query document that specifies the criteria used to remove a document.
1721-
* @param collectionName name of the collection where the documents will be removed from, must not be {@literal null} or empty.
1719+
* @param collectionName name of the collection where the documents will be removed from, must not be {@literal null}
1720+
* or empty.
17221721
* @return the {@link DeleteResult} which lets you access the results of the previous delete.
17231722
* @throws IllegalArgumentException when {@literal query} or {@literal collectionName} is {@literal null}.
17241723
*/
@@ -1730,7 +1729,8 @@ default long exactCount(Query query, String collectionName) {
17301729
* information. Use {@link #findAllAndRemove(Query, Class, String)} to get full type specific support.
17311730
*
17321731
* @param query the query document that specifies the criteria used to find and remove documents.
1733-
* @param collectionName name of the collection where the documents will be removed from, must not be {@literal null} or empty.
1732+
* @param collectionName name of the collection where the documents will be removed from, must not be {@literal null}
1733+
* or empty.
17341734
* @return the {@link List} converted objects deleted by this operation.
17351735
* @since 1.5
17361736
*/
@@ -1755,7 +1755,8 @@ default long exactCount(Query query, String collectionName) {
17551755
*
17561756
* @param query the query document that specifies the criteria used to find and remove documents.
17571757
* @param entityClass class of the pojo to be operated on.
1758-
* @param collectionName name of the collection where the documents will be removed from, must not be {@literal null} or empty.
1758+
* @param collectionName name of the collection where the documents will be removed from, must not be {@literal null}
1759+
* or empty.
17591760
* @return the {@link List} converted objects deleted by this operation.
17601761
* @since 1.5
17611762
*/

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/LazyLoadingProxyFactory.java

+8-16
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
import java.io.ObjectOutputStream;
2323
import java.io.Serializable;
2424
import java.lang.reflect.Method;
25-
import java.util.concurrent.locks.Lock;
2625
import java.util.concurrent.locks.ReadWriteLock;
2726
import java.util.concurrent.locks.ReentrantReadWriteLock;
2827
import java.util.function.Supplier;
@@ -42,6 +41,8 @@
4241
import org.springframework.data.mongodb.ClientSessionException;
4342
import org.springframework.data.mongodb.LazyLoadingException;
4443
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
44+
import org.springframework.data.mongodb.util.Lock;
45+
import org.springframework.data.mongodb.util.Lock.AcquiredLock;
4546
import org.springframework.lang.Nullable;
4647
import org.springframework.objenesis.SpringObjenesis;
4748
import org.springframework.util.ReflectionUtils;
@@ -175,7 +176,10 @@ public static class LazyLoadingInterceptor
175176
}
176177
}
177178

178-
private final ReadWriteLock lock = new ReentrantReadWriteLock();
179+
private final ReadWriteLock l = new ReentrantReadWriteLock();
180+
181+
private final Lock readLock = Lock.of(l.readLock());
182+
private final Lock writeLock = Lock.of(l.writeLock());
179183

180184
private final MongoPersistentProperty property;
181185
private final DbRefResolverCallback callback;
@@ -347,8 +351,7 @@ private void readObject(ObjectInputStream in) throws IOException {
347351
@Nullable
348352
private Object resolve() {
349353

350-
lock.readLock().lock();
351-
try {
354+
try (AcquiredLock l = readLock.lock()) {
352355
if (resolved) {
353356

354357
if (LOGGER.isTraceEnabled()) {
@@ -357,8 +360,6 @@ private Object resolve() {
357360
}
358361
return result;
359362
}
360-
} finally {
361-
lock.readLock().unlock();
362363
}
363364

364365
if (LOGGER.isTraceEnabled()) {
@@ -367,7 +368,7 @@ private Object resolve() {
367368
}
368369

369370
try {
370-
return executeWhileLocked(lock.writeLock(), () -> callback.resolve(property));
371+
return writeLock.execute(() -> callback.resolve(property));
371372
} catch (RuntimeException ex) {
372373

373374
DataAccessException translatedException = exceptionTranslator.translateExceptionIfPossible(ex);
@@ -381,15 +382,6 @@ private Object resolve() {
381382
}
382383
}
383384

384-
private static <T> T executeWhileLocked(Lock lock, Supplier<T> stuff) {
385-
386-
lock.lock();
387-
try {
388-
return stuff.get();
389-
} finally {
390-
lock.unlock();
391-
}
392-
}
393385
}
394386

395387
}

0 commit comments

Comments
 (0)