Skip to content

Transaction Support #1487

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
</parent>

<properties>
<couchbase>3.3.0</couchbase>
<couchbase.osgi>3.3.0</couchbase.osgi>
<couchbase>3.3.2-SNAPSHOT</couchbase>
<couchbase.osgi>3.3.2-SNAPSHOT</couchbase.osgi>
<springdata.commons>3.0.0-SNAPSHOT</springdata.commons>
<java-module-name>spring.data.couchbase</java-module-name>
<jodatime>2.10.13</jodatime>
Expand Down Expand Up @@ -286,6 +286,7 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<configuration>
<useModulePath>false</useModulePath>
<includes>
<include>**/*IntegrationTest.java</include>
<include>**/*IntegrationTests.java</include>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
/*
* Copyright 2021-2022 the original author or authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.couchbase.client.java.transactions;

import com.couchbase.client.core.annotation.Stability;
import com.couchbase.client.core.transaction.CoreTransactionAttemptContext;
import com.couchbase.client.java.codec.JsonSerializer;

/**
* To access the ReactiveTransactionAttemptContext held by TransactionAttemptContext
*
* @author Michael Reiche
*/
@Stability.Internal
public class AttemptContextReactiveAccessor {
public static ReactiveTransactionAttemptContext createReactiveTransactionAttemptContext(
CoreTransactionAttemptContext core, JsonSerializer jsonSerializer) {
return new ReactiveTransactionAttemptContext(core, jsonSerializer);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2021 the original author or authors
* Copyright 2012-2022 the original author or authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -97,9 +97,11 @@ public Scope getScope() {
@Override
public Collection getCollection(final String collectionName) {
final Scope scope = getScope();
if (collectionName == null) {
if (!scope.name().equals(CollectionIdentifier.DEFAULT_SCOPE)) {
throw new IllegalStateException("A collectionName must be provided if a non-default scope is used!");
if (collectionName == null || CollectionIdentifier.DEFAULT_COLLECTION.equals(collectionName)) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

better checking for invalid scope/collection specification.

if(scope != null ) {
if (scope.name() != null && !CollectionIdentifier.DEFAULT_SCOPE.equals(scope.name())) {
throw new IllegalStateException("A collectionName must be provided if a non-default scope is used");
}
}
return getBucket().defaultCollection();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Role;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.data.convert.CustomConversions;
import org.springframework.data.couchbase.CouchbaseClientFactory;
Expand All @@ -40,9 +41,16 @@
import org.springframework.data.couchbase.core.mapping.Document;
import org.springframework.data.couchbase.repository.config.ReactiveRepositoryOperationsMapping;
import org.springframework.data.couchbase.repository.config.RepositoryOperationsMapping;
import org.springframework.data.couchbase.transaction.CouchbaseCallbackTransactionManager;
import org.springframework.data.couchbase.transaction.CouchbaseTransactionInterceptor;
import org.springframework.data.couchbase.transaction.CouchbaseTransactionalOperator;
import org.springframework.data.mapping.model.CamelCaseAbbreviatingFieldNamingStrategy;
import org.springframework.data.mapping.model.FieldNamingStrategy;
import org.springframework.data.mapping.model.PropertyNameFieldNamingStrategy;
import org.springframework.transaction.TransactionManager;
import org.springframework.transaction.annotation.AnnotationTransactionAttributeSource;
import org.springframework.transaction.interceptor.TransactionAttributeSource;
import org.springframework.transaction.interceptor.TransactionInterceptor;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;

Expand Down Expand Up @@ -123,7 +131,7 @@ protected Authenticator authenticator() {
* @param couchbaseCluster the cluster reference from the SDK.
* @return the initialized factory.
*/
@Bean
@Bean(name = BeanNames.COUCHBASE_CLIENT_FACTORY)
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

make name explicit

public CouchbaseClientFactory couchbaseClientFactory(final Cluster couchbaseCluster) {
return new SimpleCouchbaseClientFactory(couchbaseCluster, getBucketName(), getScopeName());
}
Expand Down Expand Up @@ -280,9 +288,8 @@ public TranslationService couchbaseTranslationService() {

/**
* Creates a {@link CouchbaseMappingContext} equipped with entity classes scanned from the mapping base package.
*
*/
@Bean
@Bean(BeanNames.COUCHBASE_MAPPING_CONTEXT)
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

make name explicit

public CouchbaseMappingContext couchbaseMappingContext(CustomConversions customConversions) throws Exception {
CouchbaseMappingContext mappingContext = new CouchbaseMappingContext();
mappingContext.setInitialEntitySet(getInitialEntitySet());
Expand Down Expand Up @@ -310,6 +317,44 @@ public ObjectMapper couchbaseObjectMapper() {
return mapper;
}

/**
* The default blocking transaction manager. It is an implementation of CallbackPreferringTransactionManager
* CallbackPreferrringTransactionmanagers do not play well with test-cases that rely
* on @TestTransaction/@BeforeTransaction/@AfterTransaction
*
* @param clientFactory
* @return
*/
@Bean(BeanNames.COUCHBASE_TRANSACTION_MANAGER)
CouchbaseCallbackTransactionManager couchbaseTransactionManager(CouchbaseClientFactory clientFactory) {
return new CouchbaseCallbackTransactionManager(clientFactory);
}

/**
* The default TransactionalOperator.
*
* @param couchbaseCallbackTransactionManager
* @return
*/
@Bean(BeanNames.COUCHBASE_TRANSACTIONAL_OPERATOR)
public CouchbaseTransactionalOperator couchbaseTransactionalOperator(
CouchbaseCallbackTransactionManager couchbaseCallbackTransactionManager) {
return CouchbaseTransactionalOperator.create(couchbaseCallbackTransactionManager);
}

@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionInterceptor transactionInterceptor(TransactionManager couchbaseTransactionManager) {
TransactionAttributeSource transactionAttributeSource = new AnnotationTransactionAttributeSource();
TransactionInterceptor interceptor = new CouchbaseTransactionInterceptor(couchbaseTransactionManager,
transactionAttributeSource);
interceptor.setTransactionAttributeSource(transactionAttributeSource);
if (couchbaseTransactionManager != null) {
interceptor.setTransactionManager(couchbaseTransactionManager);
}
return interceptor;
}

/**
* Configure whether to automatically create indices for domain types by deriving the from the entity or not.
*/
Expand Down Expand Up @@ -375,5 +420,4 @@ private boolean nonShadowedJacksonPresent() {
public QueryScanConsistency getDefaultConsistency() {
return null;
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2021 the original author or authors
* Copyright 2012-2022 the original author or authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -59,4 +59,10 @@ public class BeanNames {
* The name for the bean that will handle reactive audit trail marking of entities.
*/
public static final String REACTIVE_COUCHBASE_AUDITING_HANDLER = "reactiveCouchbaseAuditingHandler";

public static final String COUCHBASE_CLIENT_FACTORY = "couchbaseClientFactory";

public static final String COUCHBASE_TRANSACTION_MANAGER = "couchbaseTransactionManager";

public static final String COUCHBASE_TRANSACTIONAL_OPERATOR = "couchbaseTransactionalOperator";
}
Loading