对于最新的稳定版本,请使用 Spring Data Couchbase 5.3.1Spring中文文档

对于最新的稳定版本,请使用 Spring Data Couchbase 5.3.1Spring中文文档

Couchbase 支持分布式事务。本节介绍如何将其与 Spring Data Couchbase 一起使用。Spring中文文档

要求

  • Couchbase Server 6.6.1 或更高版本。Spring中文文档

  • Spring Data Couchbase 5.0.0-M5 或更高版本。Spring中文文档

  • 应配置 NTP,以便 Couchbase 群集的节点与时间同步。不同步的时间不会导致不正确的行为,但会影响元数据清理。Spring中文文档

  • 实体类必须具有用于保存文档的 CAS 值的属性。@Version LongSpring中文文档

概述

Spring Data Couchbase 模板操作插入、查找、替换和删除,使用这些调用的存储库方法可以参与 Couchbase 事务。它们可以通过使用@Transactional注释、CouchbaseTransactionalOperator 或在 Couchbase 事务的 lambda 中执行。Spring中文文档

入门和配置

Couchbase 事务通常使用带有 @Transactional 注释的方法进行利用。 @Transactional运算符是使用 CouchbaseTransactionManager 实现的,CouchbaseTransactionManager 在 AbstractCouchbaseConfiguration 中作为 Bean 提供。 Couchbase Transactions 可以在不定义服务类的情况下使用 CouchbaseTransactionOperator,CouchbaseTransactionOperator 也在 AbtractCouchbaseConfiguration 中作为 Bean 提供。 Couchbase Transactions 也可以直接使用 lambda 中的 Spring Data Couchbase 操作 使用事务Spring中文文档

与@Transactional的交易

@Transactional将一个方法或类上的所有方法定义为事务性方法。Spring中文文档

在类级别声明此注释时,它将作为默认值应用 到声明类及其子类的所有方法。Spring中文文档

[[-属性语义]] === 属性语义Spring中文文档

在此版本中,Couchbase 事务将忽略回滚属性。 事务隔离级别为读取提交;Spring中文文档

例 1.事务配置和@Transactional使用
配置
@Configuration
@EnableCouchbaseRepositories("<parent-dir-of-repository-interfaces>")
@EnableReactiveCouchbaseRepositories("<parent-dir-of-repository-interfaces>")
@EnableTransactionManagement (1)
static class Config extends AbstractCouchbaseConfiguration {

  // Usual Setup
  @Override public String getConnectionString() { /* ... */ }
  @Override public String getUserName() { /* ... */ }
  @Override public String getPassword() { /* ... */ }
  @Override public String getBucketName() { /* ... */ }

  // Customization of transaction behavior is via the configureEnvironment() method
  @Override protected void configureEnvironment(final Builder builder) {
    builder.transactionsConfig(
      TransactionsConfig.builder().timeout(Duration.ofSeconds(30)));
  }
}
事务性服务类

请注意,如果事务失败,可以重新执行@Transactional方法的主体。 方法体中的万物必须是幂等的。Spring中文文档

import reactor.core.publisher.Mono;
import reactor.core.publisher.Flux;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

final CouchbaseOperations personOperations;
final ReactiveCouchbaseOperations reactivePersonOperations;

@Service (2)
public class PersonService {

  final CouchbaseOperations operations;
  final ReactiveCouchbaseOperations reactiveOperations;

  public PersonService(CouchbaseOperations ops, ReactiveCouchbaseOperations reactiveOps) {
    operations = ops;
    reactiveOperations = reactiveOps;
  }

  // no annotation results in this method being executed not in a transaction
  public Person save(Person p) {
    return operations.save(p);
  }

  @Transactional
  public Person changeFirstName(String id, String newFirstName) {
    Person p = operations.findById(Person.class).one(id); (3)
    return operations.replaceById(Person.class).one(p.withFirstName(newFirstName);
  }

  @Transactional
  public Mono<Person> reactiveChangeFirstName(String id, String newFirstName) {
    return personOperationsRx.findById(Person.class).one(person.id())
        .flatMap(p -> personOperationsRx.replaceById(Person.class).one(p.withFirstName(newFirstName)));
  }

}
使用 @Transactional 服务。
@Autowired PersonService personService; (4)

Person walterWhite = new Person( "Walter", "White");
Person p = personService.save(walterWhite); // this is not a transactional method
...
Person renamedPerson = personService.changeFirstName(walterWhite.getId(), "Ricky"); (5)

@Transactional方法注释的功能需要Spring中文文档

  1. 要用 @EnableTransactionManagement 注释的配置类;Spring中文文档

  2. 必须用 @Service 注释具有注释方法的服务对象;Spring中文文档

  3. 该方法的主体在事务中执行。Spring中文文档

  4. 必须通过@Autowired获取具有注释方法的服务对象。Spring中文文档

  5. 对方法的调用必须从与服务不同的类进行,因为调用 Annotated 来自同一类的方法不会调用执行事务处理的方法侦听器。Spring中文文档

与 CouchbaseTransactionalOperator 的交易

CouchbaseTransactionalOperator 可用于构造内联事务,而无需创建使用 @Transactional 的服务类。 CouchbaseTransactionalOperator 可作为 Bean 使用,并且可以使用 @Autowired 实例化。 如果显式创建一个,则必须使用 CouchbaseTransactionalOperator.create(manager) (NOT TransactionalOperator.create(manager)) 创建它。Spring中文文档

例 2.使用 TransactionalOperator.execute() 的事务访问
@Autowired TransactionalOperator txOperator;
@Autowired ReactiveCouchbaseTemplate reactiveCouchbaseTemplate;

Flux<Person> result = txOperator.execute((ctx) ->
  reactiveCouchbaseTemplate.findById(Person.class).one(person.id())
    .flatMap(p -> reactiveCouchbaseTemplate.replaceById(Person.class).one(p.withFirstName("Walt")))
 );

直接使用 SDK 进行事务处理

Spring Data Couchbase 与 Couchbase Java SDK 无缝协作以进行事务处理。Spring Data Couchbase 操作 可以在事务中执行,将直接在 transactions().run() 的 lambda 中工作,而不涉及任何 Spring 事务机制。这是在Spring Data Couchbase中利用Couchbase Transactions的最直接方法。Spring中文文档

例 3.事务访问 - 阻塞
@Autowired CouchbaseTemplate couchbaseTemplate;

TransactionResult result = couchbaseTemplate.getCouchbaseClientFactory().getCluster().transactions().run(ctx -> {
  Person p = couchbaseTemplate.findById(Person.class).one(personId);
  couchbaseTemplate.replaceById(Person.class).one(p.withFirstName("Walt"));
});
例 4.事务访问 - 反应式
@Autowired ReactiveCouchbaseTemplate reactiveCouchbaseTemplate;

Mono<TransactionResult> result = reactiveCouchbaseTemplate.getCouchbaseClientFactory().getCluster().reactive().transactions()
  .run(ctx ->
    reactiveCouchbaseTemplate.findById(Person.class).one(personId)
      .flatMap(p -> reactiveCouchbaseTemplate.replaceById(Person.class).one(p.withFirstName("Walt")))
  );