Thanks for the response and detailed explanation.
Thank you also for correcting my statement about “locks.” It does appear that we’re both referring to transaction conflicts and conflict keys.
The query was included in the first post of this thread: Concurrent upserts creating aborted transactions
and the schema is here: Upsert with multiple UIDs - #43 by devinbost
I’ll quote it here for your convenience.
type Products {
products: [Product]
}
type Product {
productId: string
options: [Option]
}
type Option {
optionId: string
color: string
}
<collectionId>: int @index(int) .
<color>: string .
<optionId>: int @index(int) .
<options>: [uid] .
<productId>: int @index(int) .
<products>: [uid] .
I’ll also quote the upsert mutation here for your convenience:
upsert {
query {
getVals(func: has(products)) {
productsUid as uid
products @filter(eq(productId, 19610626)) {
productUid as uid
options @filter(eq(optionId, 32661491)) {
optionUid as uid
}
}
}
}
mutation {
set {
uid(productsUid) <products> uid(productUid) .
uid(productsUid) <dgraph.type> "Products" .
uid(productUid) <productId> "19610626" .
uid(productUid) <options> uid(optionUid) .
uid(productUid) <dgraph.type> "Product" .
uid(optionUid) <color> "blue" .
uid(optionUid) <dgraph.type> "Option" .
uid(optionUid) <optionId> "32661491" .
}
}
}
Initially, we excluded the @upsert
directive on all fields in the schema. After we included the @upsert
directive on our predicates, however, we actually noticed a slight decrease in the ratio of transactions that were throwing the TxnConflictException
(to approximately 60% of all transactions, a noticeable decrease from approximately 80% of all transactions).
Most of the incoming messages for the upsert involve different ProductId values, so it’s very surprising that we would see so many transaction conflicts.
If Dgraph will meet our performance requirements, we are planning on running Dgraph at-scale. Our initial production requirements require us to process approximately 1,700 transactions per second with near-time latency (preferably under 300 ms), and we plan to process significantly more transactions per second (one to two orders of magnitude more) if Dgraph passes our phase 1 tests. So, meeting our scaling requirements will be critical for our use-cases.
You mentioned:
If all the nodes you’re operating on are connected to one root node in your dataset, it’s possible that multiple concurrently executing transactions can conflict with each other.
How might that happen?