Skip to content

Commit deef667

Browse files
committed
Rebased and tidied transaction branch.
Documentation to follow. Closes #1145.
1 parent e20ed08 commit deef667

File tree

114 files changed

+1403
-1348
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

114 files changed

+1403
-1348
lines changed

src/main/java/com/couchbase/client/java/transactions/AttemptContextReactiveAccessor.java

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
/*
3-
* Copyright 2021 the original author or authors
3+
* Copyright 2021-2022 the original author or authors
44
*
55
* Licensed under the Apache License, Version 2.0 (the "License");
66
* you may not use this file except in compliance with the License.
@@ -16,8 +16,6 @@
1616
*/
1717
package com.couchbase.client.java.transactions;
1818

19-
import java.lang.reflect.Field;
20-
2119
import com.couchbase.client.core.annotation.Stability;
2220
import com.couchbase.client.core.transaction.CoreTransactionAttemptContext;
2321
import com.couchbase.client.java.codec.JsonSerializer;

src/main/java/org/springframework/data/couchbase/CouchbaseClientFactory.java

+5-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2020 the original author or authors
2+
* Copyright 2012-2022 the original author or authors
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -18,9 +18,6 @@
1818

1919
import java.io.Closeable;
2020

21-
import com.couchbase.client.core.transaction.CoreTransactionAttemptContext;
22-
import com.couchbase.client.java.transactions.ReactiveTransactionAttemptContext;
23-
import com.couchbase.client.java.transactions.config.TransactionOptions;
2421
import org.springframework.dao.support.PersistenceExceptionTranslator;
2522

2623
import com.couchbase.client.java.Bucket;
@@ -31,8 +28,10 @@
3128
/**
3229
* The {@link CouchbaseClientFactory} is the main way to get access to the managed SDK instance and resources.
3330
* <p>
34-
* Please note that a single factory is always bound to a {@link Bucket}, so if you need to access more than one
35-
* you need to initialize one factory for each.
31+
* Please note that a single factory is always bound to a {@link Bucket}, so if you need to access more than one you
32+
* need to initialize one factory for each.
33+
*
34+
* @author Michael Reiche
3635
*/
3736
public interface CouchbaseClientFactory extends Closeable {
3837

src/main/java/org/springframework/data/couchbase/SimpleCouchbaseClientFactory.java

+5-11
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2021 the original author or authors
2+
* Copyright 2012-2022 the original author or authors
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -19,8 +19,6 @@
1919
import java.time.temporal.ChronoUnit;
2020
import java.util.function.Supplier;
2121

22-
import com.couchbase.client.core.transaction.CoreTransactionAttemptContext;
23-
import com.couchbase.client.java.transactions.config.TransactionOptions;
2422
import org.springframework.dao.support.PersistenceExceptionTranslator;
2523
import org.springframework.data.couchbase.core.CouchbaseExceptionTranslator;
2624

@@ -32,11 +30,7 @@
3230
import com.couchbase.client.java.ClusterOptions;
3331
import com.couchbase.client.java.Collection;
3432
import com.couchbase.client.java.Scope;
35-
import com.couchbase.client.java.codec.JsonSerializer;
3633
import com.couchbase.client.java.env.ClusterEnvironment;
37-
import com.couchbase.client.java.transactions.AttemptContextReactiveAccessor;
38-
import com.couchbase.client.java.transactions.config.TransactionsCleanupConfig;
39-
import com.couchbase.client.java.transactions.config.TransactionsConfig;
4034

4135
/**
4236
* The default implementation of a {@link CouchbaseClientFactory}.
@@ -52,18 +46,18 @@ public class SimpleCouchbaseClientFactory implements CouchbaseClientFactory {
5246
private final PersistenceExceptionTranslator exceptionTranslator;
5347

5448
public SimpleCouchbaseClientFactory(final String connectionString, final Authenticator authenticator,
55-
final String bucketName) {
49+
final String bucketName) {
5650
this(connectionString, authenticator, bucketName, null);
5751
}
5852

5953
public SimpleCouchbaseClientFactory(final String connectionString, final Authenticator authenticator,
60-
final String bucketName, final String scopeName) {
54+
final String bucketName, final String scopeName) {
6155
this(new OwnedSupplier<>(Cluster.connect(connectionString, ClusterOptions.clusterOptions(authenticator))),
6256
bucketName, scopeName);
6357
}
6458

6559
public SimpleCouchbaseClientFactory(final String connectionString, final Authenticator authenticator,
66-
final String bucketName, final String scopeName, final ClusterEnvironment environment) {
60+
final String bucketName, final String scopeName, final ClusterEnvironment environment) {
6761
this(
6862
new OwnedSupplier<>(
6963
Cluster.connect(connectionString, ClusterOptions.clusterOptions(authenticator).environment(environment))),
@@ -75,7 +69,7 @@ public SimpleCouchbaseClientFactory(final Cluster cluster, final String bucketNa
7569
}
7670

7771
private SimpleCouchbaseClientFactory(final Supplier<Cluster> cluster, final String bucketName,
78-
final String scopeName) {
72+
final String scopeName) {
7973
this.cluster = cluster;
8074
this.bucket = cluster.get().bucket(bucketName);
8175
this.scope = scopeName == null ? bucket.defaultScope() : bucket.scope(scopeName);

src/main/java/org/springframework/data/couchbase/config/AbstractCouchbaseConfiguration.java

+12-21
Original file line numberDiff line numberDiff line change
@@ -136,12 +136,7 @@ protected Authenticator authenticator() {
136136
public CouchbaseClientFactory couchbaseClientFactory(final Cluster couchbaseCluster) {
137137
return new SimpleCouchbaseClientFactory(couchbaseCluster, getBucketName(), getScopeName());
138138
}
139-
/*
140-
@Bean
141-
public ReactiveCouchbaseClientFactory reactiveCouchbaseClientFactory(final Cluster couchbaseCluster) {
142-
return new SimpleReactiveCouchbaseClientFactory(couchbaseCluster, getBucketName(), getScopeName());
143-
}
144-
*/
139+
145140
@Bean(destroyMethod = "disconnect")
146141
public Cluster couchbaseCluster(ClusterEnvironment couchbaseClusterEnvironment) {
147142
Cluster c = Cluster.connect(getConnectionString(),
@@ -171,29 +166,24 @@ protected void configureEnvironment(final ClusterEnvironment.Builder builder) {
171166

172167
@Bean(name = BeanNames.COUCHBASE_TEMPLATE)
173168
public CouchbaseTemplate couchbaseTemplate(CouchbaseClientFactory couchbaseClientFactory,
174-
MappingCouchbaseConverter mappingCouchbaseConverter, TranslationService couchbaseTranslationService) {
175-
return new CouchbaseTemplate(couchbaseClientFactory,
176-
mappingCouchbaseConverter,
177-
couchbaseTranslationService, getDefaultConsistency());
169+
MappingCouchbaseConverter mappingCouchbaseConverter, TranslationService couchbaseTranslationService) {
170+
return new CouchbaseTemplate(couchbaseClientFactory, mappingCouchbaseConverter, couchbaseTranslationService,
171+
getDefaultConsistency());
178172
}
179173

180174
public CouchbaseTemplate couchbaseTemplate(CouchbaseClientFactory couchbaseClientFactory,
181-
MappingCouchbaseConverter mappingCouchbaseConverter) {
182-
return couchbaseTemplate(couchbaseClientFactory,
183-
mappingCouchbaseConverter,
184-
new JacksonTranslationService());
175+
MappingCouchbaseConverter mappingCouchbaseConverter) {
176+
return couchbaseTemplate(couchbaseClientFactory, mappingCouchbaseConverter, new JacksonTranslationService());
185177
}
186178

187179
@Bean(name = BeanNames.REACTIVE_COUCHBASE_TEMPLATE)
188-
public ReactiveCouchbaseTemplate reactiveCouchbaseTemplate(
189-
CouchbaseClientFactory couchbaseClientFactory,
180+
public ReactiveCouchbaseTemplate reactiveCouchbaseTemplate(CouchbaseClientFactory couchbaseClientFactory,
190181
MappingCouchbaseConverter mappingCouchbaseConverter, TranslationService couchbaseTranslationService) {
191-
return new ReactiveCouchbaseTemplate(couchbaseClientFactory, mappingCouchbaseConverter,
192-
couchbaseTranslationService, getDefaultConsistency());
182+
return new ReactiveCouchbaseTemplate(couchbaseClientFactory, mappingCouchbaseConverter, couchbaseTranslationService,
183+
getDefaultConsistency());
193184
}
194185

195-
public ReactiveCouchbaseTemplate reactiveCouchbaseTemplate(
196-
CouchbaseClientFactory couchbaseClientFactory,
186+
public ReactiveCouchbaseTemplate reactiveCouchbaseTemplate(CouchbaseClientFactory couchbaseClientFactory,
197187
MappingCouchbaseConverter mappingCouchbaseConverter) {
198188
return reactiveCouchbaseTemplate(couchbaseClientFactory, mappingCouchbaseConverter,
199189
new JacksonTranslationService());
@@ -358,7 +348,8 @@ public CouchbaseTransactionalOperator transactionalOperator(
358348
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
359349
public TransactionInterceptor transactionInterceptor(TransactionManager couchbaseTransactionManager) {
360350
TransactionAttributeSource transactionAttributeSource = new AnnotationTransactionAttributeSource();
361-
TransactionInterceptor interceptor = new CouchbaseTransactionInterceptor(couchbaseTransactionManager, transactionAttributeSource);
351+
TransactionInterceptor interceptor = new CouchbaseTransactionInterceptor(couchbaseTransactionManager,
352+
transactionAttributeSource);
362353
interceptor.setTransactionAttributeSource(transactionAttributeSource);
363354
if (couchbaseTransactionManager != null) {
364355
interceptor.setTransactionManager(couchbaseTransactionManager);

src/main/java/org/springframework/data/couchbase/config/BeanNames.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2021 the original author or authors
2+
* Copyright 2012-2022 the original author or authors
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -64,5 +64,5 @@ public class BeanNames {
6464

6565
public static final String COUCHBASE_TRANSACTION_MANAGER = "couchbaseTransactionManager";
6666

67-
public static final String COUCHBASE_TRANSACTIONAL_OPERATOR = "couchbaseTransactionalOperator" ;
67+
public static final String COUCHBASE_TRANSACTIONAL_OPERATOR = "couchbaseTransactionalOperator";
6868
}

src/main/java/org/springframework/data/couchbase/core/AbstractTemplateSupport.java

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2021 the original author or authors
2+
* Copyright 2022 the original author or authors
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -41,6 +41,12 @@
4141

4242
import com.couchbase.client.core.error.CouchbaseException;
4343

44+
45+
/**
46+
* Base shared by Reactive and non-Reactive TemplateSupport
47+
*
48+
* @author Michael Reiche
49+
*/
4450
public abstract class AbstractTemplateSupport {
4551

4652
final ReactiveCouchbaseTemplate template;

src/main/java/org/springframework/data/couchbase/core/CouchbaseExceptionTranslator.java

+26-6
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,39 @@
1919
import java.util.ConcurrentModificationException;
2020
import java.util.concurrent.TimeoutException;
2121

22-
import com.couchbase.client.core.error.transaction.TransactionOperationFailedException;
2322
import org.springframework.dao.DataAccessException;
2423
import org.springframework.dao.DataAccessResourceFailureException;
2524
import org.springframework.dao.DataIntegrityViolationException;
2625
import org.springframework.dao.DataRetrievalFailureException;
2726
import org.springframework.dao.DuplicateKeyException;
2827
import org.springframework.dao.InvalidDataAccessResourceUsageException;
29-
import org.springframework.dao.OptimisticLockingFailureException;;
28+
import org.springframework.dao.OptimisticLockingFailureException;
3029
import org.springframework.dao.QueryTimeoutException;
3130
import org.springframework.dao.TransientDataAccessResourceException;
3231
import org.springframework.dao.support.PersistenceExceptionTranslator;
33-
34-
import com.couchbase.client.core.error.*;
3532
import org.springframework.data.couchbase.transaction.error.UncategorizedTransactionDataAccessException;
3633

34+
import com.couchbase.client.core.error.BucketNotFoundException;
35+
import com.couchbase.client.core.error.CasMismatchException;
36+
import com.couchbase.client.core.error.CollectionNotFoundException;
37+
import com.couchbase.client.core.error.ConfigException;
38+
import com.couchbase.client.core.error.DecodingFailureException;
39+
import com.couchbase.client.core.error.DesignDocumentNotFoundException;
40+
import com.couchbase.client.core.error.DocumentExistsException;
41+
import com.couchbase.client.core.error.DocumentLockedException;
42+
import com.couchbase.client.core.error.DocumentNotFoundException;
43+
import com.couchbase.client.core.error.DurabilityAmbiguousException;
44+
import com.couchbase.client.core.error.DurabilityImpossibleException;
45+
import com.couchbase.client.core.error.DurabilityLevelNotAvailableException;
46+
import com.couchbase.client.core.error.EncodingFailureException;
47+
import com.couchbase.client.core.error.ReplicaNotConfiguredException;
48+
import com.couchbase.client.core.error.RequestCanceledException;
49+
import com.couchbase.client.core.error.ScopeNotFoundException;
50+
import com.couchbase.client.core.error.ServiceNotAvailableException;
51+
import com.couchbase.client.core.error.TemporaryFailureException;
52+
import com.couchbase.client.core.error.ValueTooLargeException;
53+
import com.couchbase.client.core.error.transaction.TransactionOperationFailedException;
54+
3755
/**
3856
* Simple {@link PersistenceExceptionTranslator} for Couchbase.
3957
* <p>
@@ -43,6 +61,8 @@
4361
*
4462
* @author Michael Nitschinger
4563
* @author Simon Baslé
64+
* @author Michael Reiche
65+
* @author Graham Pople
4666
*/
4767
public class CouchbaseExceptionTranslator implements PersistenceExceptionTranslator {
4868

@@ -73,7 +93,7 @@ public final DataAccessException translateExceptionIfPossible(final RuntimeExcep
7393
return new OptimisticLockingFailureException(ex.getMessage(), ex);
7494
}
7595

76-
if ( ex instanceof ReplicaNotConfiguredException || ex instanceof DurabilityLevelNotAvailableException
96+
if (ex instanceof ReplicaNotConfiguredException || ex instanceof DurabilityLevelNotAvailableException
7797
|| ex instanceof DurabilityImpossibleException || ex instanceof DurabilityAmbiguousException) {
7898
return new DataIntegrityViolationException(ex.getMessage(), ex);
7999
}
@@ -102,7 +122,7 @@ public final DataAccessException translateExceptionIfPossible(final RuntimeExcep
102122

103123
if (ex instanceof TransactionOperationFailedException) {
104124
// Replace the TransactionOperationFailedException, since we want the Spring operation to fail with a
105-
// Spring error. Internal state has already been set in the AttemptContext so the retry, rollback etc.
125+
// Spring error. Internal state has already been set in the AttemptContext so the retry, rollback etc.
106126
// will get respected regardless of what gets propagated (or not) from the lambda.
107127
return new UncategorizedTransactionDataAccessException((TransactionOperationFailedException) ex);
108128
}

src/main/java/org/springframework/data/couchbase/core/CouchbaseOperations.java

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2020 the original author or authors
2+
* Copyright 2012-2022 the original author or authors
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -20,12 +20,12 @@
2020
import org.springframework.data.couchbase.core.convert.CouchbaseConverter;
2121
import org.springframework.data.couchbase.core.query.Query;
2222

23-
import static org.springframework.data.couchbase.repository.support.Util.hasNonZeroVersionProperty;
24-
2523
import com.couchbase.client.java.query.QueryScanConsistency;
2624

2725
/**
2826
* Defines common operations on the Couchbase data source, most commonly implemented by {@link CouchbaseTemplate}.
27+
*
28+
* @author Michael Reiche
2929
*/
3030
public interface CouchbaseOperations extends FluentCouchbaseOperations {
3131

@@ -41,6 +41,7 @@ public interface CouchbaseOperations extends FluentCouchbaseOperations {
4141

4242
/**
4343
* The name of the scope used, null if the default scope is used.
44+
* todo mr - not used?
4445
*/
4546
String getScopeName();
4647

@@ -53,7 +54,8 @@ public interface CouchbaseOperations extends FluentCouchbaseOperations {
5354
* Returns the default consistency to use for queries
5455
*/
5556
QueryScanConsistency getConsistency();
56-
<T> T save(T entity);
57+
58+
<T> T save(T entity, String... scopeAndCollection);
5759

5860
<T> Long count(Query query, Class<T> domainType);
5961

src/main/java/org/springframework/data/couchbase/core/CouchbaseTemplate.java

+14-25
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2021 the original author or authors
2+
* Copyright 2012-2022 the original author or authors
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,8 +16,6 @@
1616

1717
package org.springframework.data.couchbase.core;
1818

19-
import static org.springframework.data.couchbase.repository.support.Util.hasNonZeroVersionProperty;
20-
2119
import org.springframework.beans.BeansException;
2220
import org.springframework.context.ApplicationContext;
2321
import org.springframework.context.ApplicationContextAware;
@@ -55,27 +53,22 @@ public class CouchbaseTemplate implements CouchbaseOperations, ApplicationContex
5553
private final QueryScanConsistency scanConsistency;
5654
private @Nullable CouchbasePersistentEntityIndexCreator indexCreator;
5755

58-
public CouchbaseTemplate(final CouchbaseClientFactory clientFactory,
59-
final CouchbaseConverter converter) {
60-
this(clientFactory,
61-
converter, new JacksonTranslationService());
56+
public CouchbaseTemplate(final CouchbaseClientFactory clientFactory, final CouchbaseConverter converter) {
57+
this(clientFactory, converter, new JacksonTranslationService());
6258
}
6359

64-
public CouchbaseTemplate(final CouchbaseClientFactory clientFactory,
65-
CouchbaseConverter converter,
66-
final TranslationService translationService) {
67-
this(clientFactory,
68-
converter, translationService, null);
60+
public CouchbaseTemplate(final CouchbaseClientFactory clientFactory, CouchbaseConverter converter,
61+
final TranslationService translationService) {
62+
this(clientFactory, converter, translationService, null);
6963
}
7064

71-
public CouchbaseTemplate(final CouchbaseClientFactory clientFactory,
72-
final CouchbaseConverter converter,
73-
final TranslationService translationService, QueryScanConsistency scanConsistency) {
65+
public CouchbaseTemplate(final CouchbaseClientFactory clientFactory, final CouchbaseConverter converter,
66+
final TranslationService translationService, QueryScanConsistency scanConsistency) {
7467
this.clientFactory = clientFactory;
7568
this.converter = converter;
7669
this.templateSupport = new CouchbaseTemplateSupport(this, converter, translationService);
77-
this.reactiveCouchbaseTemplate = new ReactiveCouchbaseTemplate(clientFactory, converter,
78-
translationService, scanConsistency);
70+
this.reactiveCouchbaseTemplate = new ReactiveCouchbaseTemplate(clientFactory, converter, translationService,
71+
scanConsistency);
7972
this.scanConsistency = scanConsistency;
8073

8174
this.mappingContext = this.converter.getMappingContext();
@@ -87,16 +80,12 @@ public CouchbaseTemplate(final CouchbaseClientFactory clientFactory,
8780
}
8881
}
8982

90-
public <T> T save(T entity) {
91-
if (hasNonZeroVersionProperty(entity, templateSupport.converter)) {
92-
return replaceById((Class<T>) entity.getClass()).one(entity);
93-
//} else if (getTransactionalOperator() != null) {
94-
// return insertById((Class<T>) entity.getClass()).one(entity);
95-
} else {
96-
return upsertById((Class<T>) entity.getClass()).one(entity);
97-
}
83+
@Override
84+
public <T> T save(T entity, String... scopeAndCollection) {
85+
return reactive().save(entity, scopeAndCollection).block();
9886
}
9987

88+
@Override
10089
public <T> Long count(Query query, Class<T> domainType) {
10190
return findByQuery(domainType).matching(query).count();
10291
}

0 commit comments

Comments
 (0)