They happen when concurrent transactions try to update the same documents/keys, so one transaction must abort to keep isolation. Apps should treat these as retryable: retry the whole transaction (with backoff), keep transactions short, and make side effects idempotent so retries are safe.
Expanding on the short answer — what usually matters in practice:
A tiny example (query + projection):
// Example: query + projection
const user = await db.collection('users').findOne(
{ email: '[email protected]' },
{ projection: { _id: 0, email: 1, name: 1 } },
)