1. 序章

Spring Data Couchbase の紹介の後、この2番目のチュートリアルでは、エンティティ検証(JSR-303)、楽観的ロック、およびCouchbaseドキュメントデータベースのさまざまなレベルのクエリ整合性のサポートに焦点を当てます。

2. エンティティの検証

Spring Data Couchbaseは、JSR-303エンティティ検証アノテーションのサポートを提供します。 この機能を利用するために、最初にJSR-303ライブラリをMavenプロジェクトの依存関係セクションに追加します。

<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>1.1.0.Final</version>
</dependency>

次に、JSR-303の実装を追加します。 Hibernate実装を使用します:

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>5.2.4.Final</version>
</dependency>

最後に、バリデーターファクトリBeanと対応するCouchbaseイベントリスナーをCouchbase構成に追加します。

@Bean
public LocalValidatorFactoryBean localValidatorFactoryBean() {
    return new LocalValidatorFactoryBean();
}

@Bean
public ValidatingCouchbaseEventListener validatingCouchbaseEventListener() {
    return new ValidatingCouchbaseEventListener(localValidatorFactoryBean());
}

同等のXML構成は次のようになります。

<bean id="validator"
  class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>

<bean id="validatingEventListener" 
  class="org.springframework.data.couchbase.core.mapping.event.ValidatingCouchbaseEventListener"/>

次に、エンティティクラスにJSR-303アノテーションを追加します。 永続化操作中に制約違反が発生すると、操作は失敗し、ConstraintViolationExceptionがスローされます。

Studentエンティティに関連して適用できる制約のサンプルを次に示します。

@Field
@NotNull
@Size(min=1, max=20)
@Pattern(regexp="^[a-zA-Z .'-]+$")
private String firstName;

...
@Field
@Past
private DateTime dateOfBirth;

3. 楽観的なロック

Spring Data Couchbaseは、Spring DataJPA( @Transactional アノテーションを介して)などの他のSpringDataモジュールで実現できるものと同様のマルチドキュメントトランザクションをサポートしていません。また、ロールバック機能も提供していません。

ただし、 @Version アノテーションを使用することで、他のSpringDataモジュールとほぼ同じ方法で楽観的ロックをサポートします。

@Version
private long version;

Couchbaseは、「コンペアアンドスワップ」(CAS)メカニズムと呼ばれるメカニズムを使用して、データストアレベルで楽観的なロックを実現します。

Couchbaseの各ドキュメントには、ドキュメントのメタデータまたはコンテンツが変更されるたびに自動的に変更されるCAS値が関連付けられています。 フィールドで@Versionアノテーションを使用すると、ドキュメントがCouchbaseから取得されるたびに、そのフィールドに現在のCAS値が入力されます。

ドキュメントをCouchbaseに保存し直そうとすると、このフィールドはCouchbaseの現在のCAS値と照合されます。 値が一致しない場合、永続化操作はOptimisticLockingExceptionで失敗します。

コード内のこのフィールドにアクセスしたり変更したりしないように注意することは、非常に重要です

4. クエリの一貫性

Couchbaseに永続レイヤーを実装するときは、古い読み取りと書き込みの可能性を考慮する必要があります。 これは、ドキュメントが挿入、更新、または削除されるときに、これらの変更を反映するためにバッキングビューとインデックスが更新されるまでに時間がかかる場合があるためです。

また、Couchbaseノードのクラスターに裏打ちされた大規模なデータセットがある場合、これは特にOLTPシステムにとって重大な問題になる可能性があります。

Spring Dataは、一部のリポジトリおよびテンプレート操作に堅牢なレベルの整合性を提供し、さらに、アプリケーションで許容できる読み取りおよび書き込みの整合性のレベルを決定できるいくつかのオプションを提供します。

4.1. 一貫性のレベル

Spring Dataでは、org.springframework.data.couchbase.core.queryパッケージにあるConsistency列挙型を使用して、アプリケーションのさまざまなレベルのクエリの一貫性と失効性を指定できます。

この列挙型は、クエリの一貫性と失効の次のレベルを、最も厳密なものから最も厳密なものまで定義します。

  • 結果整合性
    • 古い読み取りは許可されます
    • インデックスはCouchbaseの標準アルゴリズムに従って更新されます
  • UPDATE_AFTER
    • 古い読み取りは許可されます
    • インデックスは各リクエストの後に更新されます
  • DEFAULT_CONSISTENCY READ_YOUR_OWN_WRITES と同じ)
  • READ_YOUR_OWN_WRITES
    • 古い読み取りは許可されていません
    • インデックスは各リクエストの後に更新されます
  • STRONGLY_CONSISTENT
    • 古い読み取りは許可されていません
    • インデックスは各ステートメントの後に更新されます

4.2. デフォルトの動作

Couchbaseから削除されたドキュメントがあり、バッキングビューとインデックスが完全に更新されていない場合を考えてみます。

CouchbaseRepository組み込みメソッドdeleteAll()は、バッキングビューによって検出されたが、削除がビューにまだ反映されていないドキュメントを安全に無視します。

同様に、CouchbaseTemplate組み込みメソッドfindByViewおよびfindBySpatialViewは、バッキングビューで最初に検出されたが、削除されてから。

この記事の執筆時点での公式のSpringDataCouchbase 2.1.xドキュメントによると、他のすべてのテンプレートメソッド、組み込みリポジトリメソッド、および派生リポジトリクエリメソッドについて、SpringDataはデフォルトの整合性レベルConsistency.READ_YOUR_OWN_WRITESを使用します。[ X272X]

以前のバージョンのライブラリでは、デフォルトのConsistency.UPDATE_AFTERが使用されていたことは注目に値します。

次のサブセクションで説明するように、使用しているバージョンに関係なく、提供されているデフォルトの整合性レベルを盲目的に受け入れることについて予約がある場合、Springは使用されている整合性レベルを宣言的に制御できる2つの方法を提供します。

4.3. グローバル整合性設定

Couchbaseリポジトリを使用していて、アプリケーションがより強いレベルの整合性を要求する場合、またはより弱いレベルを許容できる場合は、 getDefaultConsistency()メソッドをオーバーライドすることで、すべてのリポジトリのデフォルトの整合性設定をオーバーライドできます。 Couchbase構成で。

Couchbase構成クラスでグローバル整合性レベルをオーバーライドする方法は次のとおりです。

@Override
public Consistency getDefaultConsistency() {
    return Consistency.STRONGLY_CONSISTENT;
}

同等のXML構成は次のとおりです。

<couchbase:template consistency="STRONGLY_CONSISTENT"/>

より厳密なレベルの整合性の代償は、クエリ時のレイテンシーの増加であることに注意してください。したがって、アプリケーションのニーズに基づいてこの設定を調整するようにしてください。

たとえば、データがバッチでのみ追加または更新されることが多いデータウェアハウスまたはレポートアプリケーションは、 EVENTUALLY_CONSISTENT の候補として適していますが、OLTPアプリケーションはおそらくなどのより厳密なレベルに向かう傾向があります。 X264X]READ_YOUR_OWN_WRITESまたはSTRONGLY_CONSISTENT

4.4. カスタム整合性の実装

より細かく調整された整合性設定が必要な場合は、整合性レベルを個別に制御するクエリに独自のリポジトリ実装を提供し、 queryViewを使用することで、クエリごとにデフォルトの整合性レベルをオーバーライドできます。 および/またはqueryN1QLメソッドはCouchbaseTemplateによって提供されます。

古い読み取りを許可したくないStudentエンティティに対して、findByFirstNameStartsWithというカスタムリポジトリメソッドを実装しましょう。

まず、カスタムメソッド宣言を含むインターフェイスを作成します。

public interface CustomStudentRepository {
    List<Student> findByFirstNameStartsWith(String s);
}

次に、インターフェイスを実装し、基になるCouchbaseJavaSDKのStale設定を目的のレベルに設定します。

public class CustomStudentRepositoryImpl implements CustomStudentRepository {

    @Autowired
    private CouchbaseTemplate template;

    public List<Student> findByFirstNameStartsWith(String s) {
        return template.findByView(ViewQuery.from("student", "byFirstName")
          .startKey(s)
          .stale(Stale.FALSE),
          Student.class);
    }
}

最後に、標準リポジトリインターフェイスで汎用 CrudRepository インターフェイスとカスタムリポジトリインターフェイスの両方を拡張することで、クライアントは標準リポジトリインターフェイスのすべての組み込みメソッドと派生メソッドに加えて、カスタムメソッドにアクセスできるようになります。カスタムリポジトリクラスに実装:

public interface StudentRepository extends CrudRepository<Student, String>,
  CustomStudentRepository {
    ...
}

5. 結論

このチュートリアルでは、Spring Data Couchbaseコミュニティプロジェクトを使用するときに、JSR-303エンティティの検証を実装し、楽観的なロック機能を実現する方法を示しました。

また、Couchbaseでのクエリの一貫性を理解する必要性についても説明し、SpringDataCouchbaseが提供するさまざまなレベルの一貫性を紹介しました。

最後に、Spring Data Couchbaseがグローバルに使用するデフォルトの整合性レベルといくつかの特定のメソッドについて説明し、グローバルなデフォルトの整合性設定をオーバーライドする方法と、クエリごとに整合性設定をオーバーライドする方法を示しました。独自のカスタムリポジトリの実装。

このチュートリアルの完全なソースコードは、GitHubプロジェクトで表示できます。

Spring Data Couchbaseの詳細については、公式の Spring DataCouchbaseプロジェクトサイトにアクセスしてください。