Docs Menu
Docs Home
/
MongoDB 매뉴얼
/ /

읽기 격리, 일관성 및 최신성

이 페이지의 내용

  • 격리 보장
  • 단조적 쓰기
  • 실시간 주문 처리
  • 인과 관계 일관성

읽기 고려에 따라 클라이언트는 쓰기가 지속형이 되기 전에 쓰기 결과를 확인할 수 있습니다.

다중 문서 트랜잭션 트랜잭션이 커밋되면 트랜잭션에서 이루어진 모든 데이터 변경 사항이 저장되고 트랜잭션 외부에서 볼 수 있습니다. 즉, 트랜잭션은 다른 트랜잭션을 롤백하는 동안 일부 변경 사항을 커밋하지 않습니다.

트랜잭션이 커밋될 때까지 트랜잭션에서 변경된 데이터는 트랜잭션 외부에 표시되지 않습니다.

그러나 트랜잭션이 여러 샤드에 쓰기를 수행하는 경우, 모든 외부 읽기 작업이 커밋된 트랜잭션의 결과가 샤드 전체에 표시될 때까지 기다릴 필요는 없습니다. 예를 들어, 트랜잭션이 커밋되고 쓰기 1이 샤드 A에 표시되지만 쓰기 2가 샤드 B에 아직 표시되지 않는 경우, 읽기 고려 "local"의 외부 읽기는 쓰기 2를 보지 않고 쓰기 1의 결과를 읽을 수 있습니다.

커밋되지 않은 읽기는 기본 격리 수준이며 mongod 독립형 인스턴스와 복제본 세트 및 샤딩된 클러스터에 적용됩니다.

쓰기 작업은 단일 문서에 대해 원자적으로 이루어집니다. 이는 쓰기 작업이 문서의 여러 필드를 업데이트하더라도 읽기 작업에서는 일부 필드만 업데이트된 상태의 문서를 절대 볼 수 없다는 것을 의미합니다. 그러나 클라이언트는 부분적으로 업데이트된 문서를 볼 수 없지만, 커밋되지 않은 읽기는 동시 읽기 작업에서 변경 사항이 지속적으로 적용되기 전에 업데이트된 문서를 볼 수 있다는 것을 의미합니다.

독립형 mongod 인스턴스를 사용하면 단일 문서에 대한 읽기 및 쓰기 작업 세트를 직렬화할 수 있습니다. 복제본 세트를 사용하면 단일 문서에 대한 읽기 및 쓰기 작업 세트는 롤백이 없는 경우에 직렬화할 수 있습니다.

단일 쓰기 작업(예: db.collection.updateMany())이 여러 문서를 수정하는 경우 각 문서의 수정은 원자적이지만 전체 작업은 원자적이지 않습니다.

단일 쓰기 작업이든 다중 쓰기 작업이든 다중 문서 쓰기 작업을 수행할 때 다른 작업과 겹칠 수 있습니다.

여러 문서(단일 또는 여러 컬렉션)에 대한 읽기 및 쓰기의 원자성이 필요한 상황의 경우, 복제본 세트 및 샤딩된 클러스터에서의 트랜잭션을 포함한 분산 트랜잭션을 지원합니다.

자세한 내용은 거래를참조하세요.

중요

대부분의 경우 분산 트랜잭션은 단일 문서 쓰기에 비해 더 큰 성능 비용이 발생하므로 분산 트랜잭션의 가용성이 효과적인 스키마 설계를 대체할 수는 없습니다. 대부분의 시나리오에서 비정규화된 데이터 모델 (내장된 문서 및 배열) 은 계속해서 데이터 및 사용 사례에 최적일 것입니다. 즉, 대부분의 시나리오에서 데이터를 적절하게 모델링하면 분산 트랜잭션의 필요성이 최소화됩니다.

추가 트랜잭션 사용 고려 사항(예: 런타임 제한 및 oplog 크기 제한)은 프로덕션 고려사항을 참조하세요.

다중 문서 쓰기 작업을 분리하지 않으면 MongoDB는 다음과 같은 동작을 보입니다.

  1. Non-point 읽기 작업. 읽기 작업이 시간 t 1에 시작되어 문서 읽기를 시작한다고 가정합니다. 그런 다음 쓰기 작업은 나중에 어느 시점( t 2)에 문서 중 하나를 업데이트하면, 읽기 작업은 업데이트된 버전의 문서만 볼 수 있으므로 데이터의 특정 시점 스냅샷을 볼 수 없습니다.

  2. 직렬화할 수 없는 작업입니다. 읽기 작업이 시간 t 1에 문서 d 1을 읽고, 쓰기 작업이 나중에 시간 t 3에 문서 d 1을 업데이트한다고 가정해 보겠습니다. 이로 인해 읽기-쓰기 종속성이 발생합니다. 즉, 작업을 직렬화하려는 경우 읽기 작업이 쓰기 작업보다 우선해야 합니다. 반면 쓰기 작업이 시간 t 2에 문서 d 2를 업데이트하고 읽기 작업이 나중에 시간 t 4에 문서 d 2를 읽는다고 가정합니다. 이렇게 하면 쓰기-읽기 종속성이 도입되어 직렬화 가능한 스케줄에서 읽기 작업이 쓰기 작업 이후에 이루어져야 합니다. 직렬화 가능성을 불가능하게 만드는 종속성 주기가 있습니다.

  3. 읽기 작업 중에 업데이트된 일치하는 문서가 누락될 수 있습니다.

MongoDB 커서는 경우에 따라 동일한 문서를 두 번 이상 반환할 수 있습니다. 커서가 문서를 반환할 때 다른 작업이 쿼리에 끼어들 수 있습니다. 이러한 작업 중 하나가 쿼리에서 사용하는 인덱스의 인덱스 필드를 변경하면 커서가 동일한 문서를 두 번 이상 반환할 수 있습니다.

고유 인덱스를 사용하는 쿼리는 경우에 따라 중복된 값을 반환할 수 있습니다. 고유 인덱스를 사용하는 커서가 동일한 고유 값을 공유하는 문서의 삭제 및 삽입과 겹치는 경우, 커서는 서로 다른 문서에서 동일한 고유 값을 두 번 반환할 수 있습니다.

읽기 격리를 사용하는 것이 좋습니다. 자세한 내용은 읽기 고려 사항 "snapshot" 을 참조하십시오.

MongoDB는 기본적으로 독립형 mongod 인스턴스 및 복제본 세트에 대해 단조로운 쓰기 보장을 제공합니다.

단조로운 쓰기 및 샤딩된 클러스터에 대해서는 인과적 일관성을 참조하세요.

프라이머리에서 "linearizable" 읽기 고려와 "majority" 쓰기 고려를 사용하면,여러 스레드가 동시에 단일 문서에 대해 읽기 및 쓰기 작업을 수행할 수 있습니다. 이는 마치 한 스레드가 실시간으로 모든 작업을 수행하는 것처럼 작동합니다. 이렇게 수행된 읽기 및 쓰기 작업은 시간적으로 일련의 순서대로 진행된 것으로 간주됩니다, 즉 이러한 작업들은 '선형화 가능한(Linearizable)' 것으로 여겨집니다.

다음도 참조하세요.

작업이 논리적으로 이전 작업에 종속되는 경우 작업 간에 인과 관계가 있습니다. 예를 들어, 지정된 조건에 따라 모든 문서를 삭제하는 쓰기 작업과 삭제 작업을 확인하는 후속 읽기 작업은 인과 관계가 있습니다.

MongoDB는 인과 관계가 일치하는 세션을 통해 인과 관계를 존중하는 순서로 인과관계 연산을 실행하고 클라이언트는 인과 관계와 일치하는 결과를 관찰합니다.

인과적 일관성을 제공하기 위해 MongoDB는 클라이언트 세션에서 인과적 일관성을 지원합니다. 인과적으로 일관된 세션은 "majority" 읽기 고려를 가진 읽기 작업과 "majority" 쓰기 고려를 가진 쓰기 작업의 관련 시퀀스가 순서에 따라 반영되는 인과 관계를 가지고 있음을 나타냅니다. 애플리케이션은 클라이언트 세션에서 한 번에 하나의 스레드만 이러한 연산을 실행하도록 해야 합니다.

인과 관계가 있는 작업의 경우:

  1. 클라이언트가 클라이언트 세션을 시작합니다.

    중요

    클라이언트 세션은 인과 관계의 일관성만 보장합니다:

    • "majority"를 사용한 읽기 작업은 대부분의 복제본 세트 노드에 의해 승인된 데이터를 반환하며, 지속성 있는 데이터입니다.

    • "majority" 쓰기 고려가 있는 쓰기 작업, 즉 복제본 세트의 투표 노드 과반수에게 작업이 적용되었다는 승인을 요청하는 쓰기 작업입니다.

    인과적 일관성 및 다양한 읽기 및 쓰기 문제에 대한 자세한 내용은 인과적 일관성 및 쓰기 고려를 참조하세요.

  2. 클라이언트가 "majority" 읽기 고려를 가진 읽기 작업과 "majority" 쓰기 고려를 가진 쓰기 작업의 시퀀스를 실행할 때 클라이언트는 각 작업에 세션 정보를 포함합니다.

  3. "majority" 읽기 고려가 있는 각 읽기 작업과 세션과 연결된 "majority" 쓰기 고려가 있는 쓰기 작업에 대해 MongoDB는 작업 오류가 발생하더라도 작업 시간과 클러스터 시간을 반환합니다. 클라이언트 세션은 작업 시간과 클러스터 시간을 추적합니다.

    참고

    MongoDB는 승인되지 않은 (w: 0)쓰기 작업에 대한 작업 시간과 클러스터 시간을 반환하지 않습니다. 승인되지 않은 쓰기는 인과 관계를 의미하지 않습니다.

    MongoDB는 클라이언트 세션에서 읽기 작업 및 승인된 쓰기 작업에 대한 작업 시간 및 클러스터 시간을 반환하지만, "majority" 읽기 고려가 있는 읽기 작업과 "majority" 쓰기 고려가 있는 쓰기 작업만 인과적 일관성을 보장할 수 있습니다. 자세한 내용은 인과적 일관성 및 읽기와 쓰기 고려를 참조하세요.

  4. 연결된 클라이언트 세션은 이 두 개의 시간 필드를 추적합니다.

    참고

    작업은 여러 세션에서 인과적으로 일관성을 유지할 수 있습니다. MongoDB 드라이버와 mongosh(은)는 클라이언트 세션의 작업 시간과 클러스터 시간을 앞당기는 방법을 제공합니다. 따라서 클라이언트는 클러스터 시간과 한 클라이언트 세션의 작업 시간을 다른 클라이언트 세션의 작업과 일치하도록 앞당길 수 있습니다.

다음 표에는 "majority" 읽기 고려가 있는 읽기 작업 및 "majority" 쓰기 고려가 있는 쓰기 작업에 대해 인과 관계가 일관적인 세션에서 제공하는 인과적 일관성 보장이 니다.나열되어 있습니다.

보장
설명

쓰기 읽기

읽기 작업은 그 앞에 있는 쓰기 작업의 결과를 반영합니다.

단조적 읽기

읽기 작업은 이전 읽기 작업보다 이전 데이터 상태에 해당하는 결과를 반환하지 않습니다.

세션에 있는 경우를 예로 들어 보겠습니다.

  • 쓰기 1은 쓰기 2보다 선행합니다.

  • 읽기 1은 읽기 2 보다 선행합니다.

  • 읽기 1은 쓰기 2를반영하는 결과를 반환합니다.

그런 다음 읽기 2는 쓰기 1의 결과를 반환할 수 없습니다.

단조로운 쓰기

다른 쓰기보다 먼저 수행되어야 하는 쓰기 작업은 다른 쓰기보다 먼저 실행됩니다.

예를 들어, 세션에서 쓰기 1이 쓰기 2보다 선행되어야 하는 경우, 쓰기 2 시점의 데이터 상태는 쓰기 1 이후의 데이터 상태를 반영해야 합니다. 다른 쓰기는 쓰기 1과 쓰기 2 사이에 끼어들 수 있지만, 쓰기 2는 쓰기 1보다 먼저 발생할 수 없습니다.

읽기 후 쓰기

읽기 작업 후에 발생해야 하는 쓰기 작업은 해당 읽기 작업 후에 실행됩니다. 즉, 쓰기 시점의 데이터 상태는 이전 읽기 작업의 데이터 상태를 반영해야 합니다

이러한 보장사항은 MongoDB 배포의 모든 노드에 대해 적용됩니다. 예를 들어, 인과적으로 일관된 세션에서 "majority" 쓰기 고려를 가진 쓰기 작업을 실행한 후 세컨더리에서 읽기를 수행하는 읽기 작업( (즉, 읽기 설정secondary)을 "majority" 읽기 고려와 함께 실행하면, 읽기 작업은 쓰기 작업 후 데이터베이스의 상태를 반영합니다.

인과적으로 일관된 세션 내의 작업은 세션 외부의 작업과 격리되지 않습니다. 동시 쓰기 작업이 세션의 쓰기와 읽기 작업 사이에 발생하는 경우, 세션의 읽기 작업은 세션의 쓰기 작업 이후에 발생한 쓰기 작업을 반영하는 결과를 반환할 수 있습니다.

애플리케이션은 클라이언트 세션에서 한 번에 하나의 스레드만 이러한 연산을 실행하도록 해야 합니다.

클라이언트는 MongoDB 3.6 이상용으로 업데이트된 MongoDB 드라이버가 필요합니다.

Java 3.6+

Python 3.6+

C 1.9 이상

Go 1.8+

C# 2.5+

노드 3.0+

Ruby 2.5+

Rust 2.1+

Swift 1.2+

Perl 2.0+

PHPC 1.4+

Scala 2.2+

C++ 3.6.6+

중요

인과적으로 일관된 세션은 "majority" 읽기 고려와 "majority" 쓰기 고려가 있는 쓰기에 대해서만 인과적 일관성을 보장할 수 있습니다.

다양한 항목에 대한 현재 및 과거 데이터를 유지하는 컬렉션 items 을 생각해 보겠습니다. 기록 데이터에만 null이 아닌 end 날짜가 있습니다. 항목의 sku 값이 변경되면 이전 sku 값이 있는 문서를 end 날짜로 업데이트한 후, 새 문서를 현재 sku 값으로 삽입해야 합니다. 클라이언트는 인과 관계가 일치하는 세션을 사용하여 삽입 전에 업데이트가 수행되도록 할 수 있습니다.


오른쪽 위에 있는 언어 선택 드롭다운 메뉴를 사용하여 이 예시의 언어를 설정하세요.


/* Use a causally-consistent session to run some operations. */
wc = mongoc_write_concern_new ();
mongoc_write_concern_set_wmajority (wc, 1000);
mongoc_collection_set_write_concern (coll, wc);
rc = mongoc_read_concern_new ();
mongoc_read_concern_set_level (rc, MONGOC_READ_CONCERN_LEVEL_MAJORITY);
mongoc_collection_set_read_concern (coll, rc);
session_opts = mongoc_session_opts_new ();
mongoc_session_opts_set_causal_consistency (session_opts, true);
session1 = mongoc_client_start_session (client, session_opts, &error);
if (!session1) {
fprintf (stderr, "couldn't start session: %s\n", error.message);
goto cleanup;
}
/* Run an update_one with our causally-consistent session. */
update_opts = bson_new ();
res = mongoc_client_session_append (session1, update_opts, &error);
if (!res) {
fprintf (stderr, "couldn't add session to opts: %s\n", error.message);
goto cleanup;
}
query = BCON_NEW ("sku", "111");
update = BCON_NEW ("$set", "{", "end",
BCON_DATE_TIME (bson_get_monotonic_time ()), "}");
res = mongoc_collection_update_one (coll,
query,
update,
update_opts,
NULL, /* reply */
&error);
if (!res) {
fprintf (stderr, "update failed: %s\n", error.message);
goto cleanup;
}
/* Run an insert with our causally-consistent session */
insert_opts = bson_new ();
res = mongoc_client_session_append (session1, insert_opts, &error);
if (!res) {
fprintf (stderr, "couldn't add session to opts: %s\n", error.message);
goto cleanup;
}
insert = BCON_NEW ("sku", "nuts-111", "name", "Pecans",
"start", BCON_DATE_TIME (bson_get_monotonic_time ()));
res = mongoc_collection_insert_one (coll, insert, insert_opts, NULL, &error);
if (!res) {
fprintf (stderr, "insert failed: %s\n", error.message);
goto cleanup;
}
using (var session1 = client.StartSession(new ClientSessionOptions { CausalConsistency = true }))
{
var currentDate = DateTime.UtcNow.Date;
var items = client.GetDatabase(
"test",
new MongoDatabaseSettings
{
ReadConcern = ReadConcern.Majority,
WriteConcern = new WriteConcern(
WriteConcern.WMode.Majority,
TimeSpan.FromMilliseconds(1000))
})
.GetCollection<BsonDocument>("items");
items.UpdateOne(session1,
Builders<BsonDocument>.Filter.And(
Builders<BsonDocument>.Filter.Eq("sku", "111"),
Builders<BsonDocument>.Filter.Eq("end", BsonNull.Value)),
Builders<BsonDocument>.Update.Set("end", currentDate));
items.InsertOne(session1, new BsonDocument
{
{"sku", "nuts-111"},
{"name", "Pecans"},
{"start", currentDate}
});
}
// Example 1: Use a causally consistent session to ensure that the update occurs before the insert.
ClientSession session1 = client.startSession(ClientSessionOptions.builder().causallyConsistent(true).build());
Date currentDate = new Date();
MongoCollection<Document> items = client.getDatabase("test")
.withReadConcern(ReadConcern.MAJORITY)
.withWriteConcern(WriteConcern.MAJORITY.withWTimeout(1000, TimeUnit.MILLISECONDS))
.getCollection("test");
items.updateOne(session1, eq("sku", "111"), set("end", currentDate));
Document document = new Document("sku", "nuts-111")
.append("name", "Pecans")
.append("start", currentDate);
items.insertOne(session1, document);
async with await client.start_session(causal_consistency=True) as s1:
current_date = datetime.datetime.today()
items = client.get_database(
"test",
read_concern=ReadConcern("majority"),
write_concern=WriteConcern("majority", wtimeout=1000),
).items
await items.update_one(
{"sku": "111", "end": None}, {"$set": {"end": current_date}}, session=s1
)
await items.insert_one(
{"sku": "nuts-111", "name": "Pecans", "start": current_date}, session=s1
)
my $s1 = $conn->start_session({ causalConsistency => 1 });
$items = $conn->get_database(
"test", {
read_concern => { level => 'majority' },
write_concern => { w => 'majority', wtimeout => 10000 },
}
)->get_collection("items");
$items->update_one(
{
sku => 111,
end => undef
},
{
'$set' => { end => $current_date}
},
{
session => $s1
}
);
$items->insert_one(
{
sku => "nuts-111",
name => "Pecans",
start => $current_date
},
{
session => $s1
}
);
$items = $client->selectDatabase(
'test',
[
'readConcern' => new \MongoDB\Driver\ReadConcern(\MongoDB\Driver\ReadConcern::MAJORITY),
'writeConcern' => new \MongoDB\Driver\WriteConcern(\MongoDB\Driver\WriteConcern::MAJORITY, 1000),
],
)->items;
$s1 = $client->startSession(
['causalConsistency' => true],
);
$currentDate = new \MongoDB\BSON\UTCDateTime();
$items->updateOne(
['sku' => '111', 'end' => ['$exists' => false]],
['$set' => ['end' => $currentDate]],
['session' => $s1],
);
$items->insertOne(
['sku' => '111-nuts', 'name' => 'Pecans', 'start' => $currentDate],
['session' => $s1],
);
with client.start_session(causal_consistency=True) as s1:
current_date = datetime.datetime.today()
items = client.get_database(
"test",
read_concern=ReadConcern("majority"),
write_concern=WriteConcern("majority", wtimeout=1000),
).items
items.update_one(
{"sku": "111", "end": None}, {"$set": {"end": current_date}}, session=s1
)
items.insert_one(
{"sku": "nuts-111", "name": "Pecans", "start": current_date}, session=s1
)
let s1 = client1.startSession(options: ClientSessionOptions(causalConsistency: true))
let currentDate = Date()
var dbOptions = MongoDatabaseOptions(
readConcern: .majority,
writeConcern: try .majority(wtimeoutMS: 1000)
)
let items = client1.db("test", options: dbOptions).collection("items")
let result1 = items.updateOne(
filter: ["sku": "111", "end": .null],
update: ["$set": ["end": .datetime(currentDate)]],
session: s1
).flatMap { _ in
items.insertOne(["sku": "nuts-111", "name": "Pecans", "start": .datetime(currentDate)], session: s1)
}
let s1 = client1.startSession(options: ClientSessionOptions(causalConsistency: true))
let currentDate = Date()
var dbOptions = MongoDatabaseOptions(
readConcern: .majority,
writeConcern: try .majority(wtimeoutMS: 1000)
)
let items = client1.db("test", options: dbOptions).collection("items")
try items.updateOne(
filter: ["sku": "111", "end": .null],
update: ["$set": ["end": .datetime(currentDate)]],
session: s1
)
try items.insertOne(["sku": "nuts-111", "name": "Pecans", "start": .datetime(currentDate)], session: s1)

다른 클라이언트가 현재 sku 값을 모두 읽어야 하는 경우, 클러스터 시간과 작업 시간을 다른 세션의 시간으로 앞당겨 이 클라이언트가 다른 세션과 인과적으로 일관성을 유지하고 두 번의 쓰기 후에 읽을 수 있도록 할 수 있습니다.

/* Make a new session, session2, and make it causally-consistent
* with session1, so that session2 will read session1's writes. */
session2 = mongoc_client_start_session (client, session_opts, &error);
if (!session2) {
fprintf (stderr, "couldn't start session: %s\n", error.message);
goto cleanup;
}
/* Set the cluster time for session2 to session1's cluster time */
cluster_time = mongoc_client_session_get_cluster_time (session1);
mongoc_client_session_advance_cluster_time (session2, cluster_time);
/* Set the operation time for session2 to session2's operation time */
mongoc_client_session_get_operation_time (session1, &timestamp, &increment);
mongoc_client_session_advance_operation_time (session2,
timestamp,
increment);
/* Run a find on session2, which should now find all writes done
* inside of session1 */
find_opts = bson_new ();
res = mongoc_client_session_append (session2, find_opts, &error);
if (!res) {
fprintf (stderr, "couldn't add session to opts: %s\n", error.message);
goto cleanup;
}
find_query = BCON_NEW ("end", BCON_NULL);
read_prefs = mongoc_read_prefs_new (MONGOC_READ_SECONDARY);
cursor = mongoc_collection_find_with_opts (coll,
query,
find_opts,
read_prefs);
while (mongoc_cursor_next (cursor, &result)) {
json = bson_as_relaxed_extended_json (result, NULL);
fprintf (stdout, "Document: %s\n", json);
bson_free (json);
}
if (mongoc_cursor_error (cursor, &error)) {
fprintf (stderr, "cursor failure: %s\n", error.message);
goto cleanup;
}
using (var session2 = client.StartSession(new ClientSessionOptions { CausalConsistency = true }))
{
session2.AdvanceClusterTime(session1.ClusterTime);
session2.AdvanceOperationTime(session1.OperationTime);
var items = client.GetDatabase(
"test",
new MongoDatabaseSettings
{
ReadPreference = ReadPreference.Secondary,
ReadConcern = ReadConcern.Majority,
WriteConcern = new WriteConcern(WriteConcern.WMode.Majority, TimeSpan.FromMilliseconds(1000))
})
.GetCollection<BsonDocument>("items");
var filter = Builders<BsonDocument>.Filter.Eq("end", BsonNull.Value);
foreach (var item in items.Find(session2, filter).ToEnumerable())
{
// process item
}
}
// Example 2: Advance the cluster time and the operation time to that of the other session to ensure that
// this client is causally consistent with the other session and read after the two writes.
ClientSession session2 = client.startSession(ClientSessionOptions.builder().causallyConsistent(true).build());
session2.advanceClusterTime(session1.getClusterTime());
session2.advanceOperationTime(session1.getOperationTime());
items = client.getDatabase("test")
.withReadPreference(ReadPreference.secondary())
.withReadConcern(ReadConcern.MAJORITY)
.withWriteConcern(WriteConcern.MAJORITY.withWTimeout(1000, TimeUnit.MILLISECONDS))
.getCollection("items");
for (Document item: items.find(session2, eq("end", BsonNull.VALUE))) {
System.out.println(item);
}
async with await client.start_session(causal_consistency=True) as s2:
s2.advance_cluster_time(s1.cluster_time)
s2.advance_operation_time(s1.operation_time)
items = client.get_database(
"test",
read_preference=ReadPreference.SECONDARY,
read_concern=ReadConcern("majority"),
write_concern=WriteConcern("majority", wtimeout=1000),
).items
async for item in items.find({"end": None}, session=s2):
print(item)
my $s2 = $conn->start_session({ causalConsistency => 1 });
$s2->advance_cluster_time( $s1->cluster_time );
$s2->advance_operation_time( $s1->operation_time );
$items = $conn->get_database(
"test", {
read_preference => 'secondary',
read_concern => { level => 'majority' },
write_concern => { w => 'majority', wtimeout => 10000 },
}
)->get_collection("items");
$cursor = $items->find( { end => undef }, { session => $s2 } );
for my $item ( $cursor->all ) {
say join(" ", %$item);
}
$s2 = $client->startSession(
['causalConsistency' => true],
);
$s2->advanceClusterTime($s1->getClusterTime());
$s2->advanceOperationTime($s1->getOperationTime());
$items = $client->selectDatabase(
'test',
[
'readPreference' => new \MongoDB\Driver\ReadPreference(\MongoDB\Driver\ReadPreference::SECONDARY),
'readConcern' => new \MongoDB\Driver\ReadConcern(\MongoDB\Driver\ReadConcern::MAJORITY),
'writeConcern' => new \MongoDB\Driver\WriteConcern(\MongoDB\Driver\WriteConcern::MAJORITY, 1000),
],
)->items;
$result = $items->find(
['end' => ['$exists' => false]],
['session' => $s2],
);
foreach ($result as $item) {
var_dump($item);
}
with client.start_session(causal_consistency=True) as s2:
s2.advance_cluster_time(s1.cluster_time)
s2.advance_operation_time(s1.operation_time)
items = client.get_database(
"test",
read_preference=ReadPreference.SECONDARY,
read_concern=ReadConcern("majority"),
write_concern=WriteConcern("majority", wtimeout=1000),
).items
for item in items.find({"end": None}, session=s2):
print(item)
let options = ClientSessionOptions(causalConsistency: true)
let result2: EventLoopFuture<Void> = client2.withSession(options: options) { s2 in
// The cluster and operation times are guaranteed to be non-nil since we already used s1 for operations above.
s2.advanceClusterTime(to: s1.clusterTime!)
s2.advanceOperationTime(to: s1.operationTime!)
dbOptions.readPreference = .secondary
let items2 = client2.db("test", options: dbOptions).collection("items")
return items2.find(["end": .null], session: s2).flatMap { cursor in
cursor.forEach { item in
print(item)
}
}
}
try client2.withSession(options: ClientSessionOptions(causalConsistency: true)) { s2 in
// The cluster and operation times are guaranteed to be non-nil since we already used s1 for operations above.
s2.advanceClusterTime(to: s1.clusterTime!)
s2.advanceOperationTime(to: s1.operationTime!)
dbOptions.readPreference = .secondary
let items2 = client2.db("test", options: dbOptions).collection("items")
for item in try items2.find(["end": .null], session: s2) {
print(item)
}
}

인메모리 구조를 빌드하는 다음 작업은 인과적으로 일관성이 없습니다.

작업
참고 사항

latencyStats 옵션이 있는 $collStats .

작업이 인과적으로 일관된 클라이언트 세션과 연결된 경우 오류를 반환합니다.

작업이 인과적으로 일관된 클라이언트 세션과 연결된 경우 오류를 반환합니다.

작업이 인과적으로 일관된 클라이언트 세션과 연결된 경우 오류를 반환합니다.

작업이 인과적으로 일관된 클라이언트 세션과 연결된 경우 오류를 반환합니다.

돌아가기

마침표 및 달러 기호