// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements.  See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You 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
//
// http://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.
= Read Repair

WARNING: Experimental API

[WARNING]
====
[discrete]
=== Limitations
A consistency check is incompatible with the following cache configurations:

* Caches without backups.
* Near caches.
* Caches that use "read-through" mode.
====


`Read Repair` refers to a technique of repairing inconsistencies between primary and backup copies of data during normal read operations. When a specific key (or keys) is read by a user operation, Ignite checks the values for the given key in all backup copies.

The `Read Repair` mode is designed to maintain consistency. However, read operations become {tilde}2 times more costly because backup copies are checked in addition to the primary copy. It is generally not advisable to use this mode all the time, but rather on a once-in-a-while basis.

To enable the `Read Repair` mode, it is necessary to obtain an instance of the cache that enables Read Repair reads as follows:

[source, java]
----
include::{javaCodeDir}/BasicCacheOperations.java[tags=read-repair, indent=0]
----

== Strategies
In case consistency violations were found, the values across the topology will be replaced by repaired values according to the chosen strategy:

[cols="1,4",opts="header"]
|===
| Strategy | Description
| `LWW` a| Last write (the newest entry) wins.

May cause IgniteException when the fix is impossible (unable to detect the newest entry)::
* Null(s) found as well as non-null values for the same key. Null (missed entry) has no version, so, it can not be compared with the versioned entry.
* Entries with the same version have different values.
| `PRIMARY` | Value from the primary node wins.
| `RELATIVE_MAJORITY` a| The relative majority, any value found more times than any other wins.
Works for an even number of copies (which is typical of Ignite) instead of an absolute majority.

May cause IgniteException when it is unable to detect values found more times than any other.

For example, when 5 copies (4 backups) are given::
* and value `A` found twice, but `X`, `Y` and `Z` only once, `A` wins,
* but, when `A` is found twice, as well as `B`, and `X` only once, the strategy is unable to determine the winner.

When 4 copies (3 backups) are given, any value found two or more times, when others are found only once, is the winner.
| `REMOVE` | Inconsistent entries will be removed.
| `CHECK_ONLY` | Only check will be performed.
|===

== Events
link:https://ignite.apache.org/releases/{version}/javadoc/org/apache/ignite/events/EventType.html#EVT_CONSISTENCY_VIOLATION[Сonsistency Violation Event] will be recorded for each violation in case it's configured as recordable. You may listen to this event to get notified about inconsistency issues.

Please, refer to the link:events/listening-to-events[Working with Events] section for the information on how to listen to events.

== Transactional Caches
Values will be repaired::
* automatically for transactions that have `TransactionConcurrency.OPTIMISTIC` concurrency mode or `TransactionIsolation.READ_COMMITTED` isolation level,

* at commit() phase for transactions that have `TransactionConcurrency.PESSIMISTIC` concurrency mode and isolation level other than `TransactionIsolation.READ_COMMITTED`

[WARNING]
====
[discrete]
=== Limitations
This proxy usage does not guarantee "all copies check" in case the value have been already cached inside the transaction.

In case you don't use a `READ_COMMITTED` isolation mode and already have a cached value, for example have already read the value or performed a write, you'll just get the cached value.
====

== Atomic Caches
Values will be repaired automatically.

[WARNING]
====
[discrete]
=== Limitations
Due to the nature of an atomic cache, false-positive results can be observed. For example, an attempt to check consistency under cache's loading may lead to a consistency violation exception.

By default, the implementation tries to check the given key three times. The number of attempts can be changed using `IgniteSystemProperties.IGNITE_NEAR_GET_MAX_REMAPS` property.
====

