| 6337 | } |
| 6338 | |
| 6339 | Future<Void> Transaction::commitMutations() { |
| 6340 | try { |
| 6341 | // if this is a read-only transaction return immediately |
| 6342 | if (!tr.transaction.write_conflict_ranges.size() && !tr.transaction.mutations.size()) { |
| 6343 | trState->numErrors = 0; |
| 6344 | |
| 6345 | trState->committedVersion = invalidVersion; |
| 6346 | trState->versionstampPromise.sendError(no_commit_version()); |
| 6347 | return Void(); |
| 6348 | } |
| 6349 | |
| 6350 | ++trState->cx->transactionsCommitStarted; |
| 6351 | |
| 6352 | if (trState->options.readOnly) |
| 6353 | return transaction_read_only(); |
| 6354 | |
| 6355 | trState->cx->mutationsPerCommit.addSample(tr.transaction.mutations.size()); |
| 6356 | trState->cx->bytesPerCommit.addSample(tr.transaction.mutations.expectedSize()); |
| 6357 | if (trState->options.tags.size()) |
| 6358 | tr.tagSet = trState->options.tags; |
| 6359 | |
| 6360 | size_t transactionSize = getSize(); |
| 6361 | if (transactionSize > (uint64_t)FLOW_KNOBS->PACKET_WARNING) { |
| 6362 | TraceEvent(!g_network->isSimulated() ? SevWarnAlways : SevWarn, "LargeTransaction") |
| 6363 | .suppressFor(1.0) |
| 6364 | .detail("Size", transactionSize) |
| 6365 | .detail("NumMutations", tr.transaction.mutations.size()) |
| 6366 | .detail("ReadConflictSize", tr.transaction.read_conflict_ranges.expectedSize()) |
| 6367 | .detail("WriteConflictSize", tr.transaction.write_conflict_ranges.expectedSize()) |
| 6368 | .detail("DebugIdentifier", trState->trLogInfo ? trState->trLogInfo->identifier : ""); |
| 6369 | } |
| 6370 | |
| 6371 | if (!apiVersionAtLeast(300)) { |
| 6372 | transactionSize = |
| 6373 | tr.transaction.mutations.expectedSize(); // Old API versions didn't account for conflict ranges when |
| 6374 | // determining whether to throw transaction_too_large |
| 6375 | } |
| 6376 | |
| 6377 | if (transactionSize > trState->options.sizeLimit) { |
| 6378 | return transaction_too_large(); |
| 6379 | } |
| 6380 | |
| 6381 | if (!readVersion.isValid()) |
| 6382 | getReadVersion( |
| 6383 | GetReadVersionRequest::FLAG_CAUSAL_READ_RISKY); // sets up readVersion field. We had no reads, so no |
| 6384 | // need for (expensive) full causal consistency. |
| 6385 | |
| 6386 | bool isCheckingWrites = trState->options.checkWritesEnabled && deterministicRandom()->random01() < 0.01; |
| 6387 | for (int i = 0; i < extraConflictRanges.size(); i++) |
| 6388 | if (extraConflictRanges[i].isReady() && |
| 6389 | extraConflictRanges[i].get().first < extraConflictRanges[i].get().second) |
| 6390 | tr.transaction.read_conflict_ranges.emplace_back( |
| 6391 | tr.arena, extraConflictRanges[i].get().first, extraConflictRanges[i].get().second); |
| 6392 | |
| 6393 | if (!trState->options.causalWriteRisky && |
| 6394 | !intersects(tr.transaction.write_conflict_ranges, tr.transaction.read_conflict_ranges).present()) |
| 6395 | makeSelfConflicting(); |
| 6396 |
no test coverage detected