{"id":"6b13ae2fc0979888","repo":"drizzle-team/drizzle-orm","slug":"rollback-6b13ae","errorCode":null,"errorMessage":"Rollback","messagePattern":"Rollback","errorType":"exception","errorClass":"TransactionRollbackError","httpStatus":null,"severity":"error","filePath":"drizzle-orm/src/singlestore-core/session.ts","lineNumber":259,"sourceCode":"export abstract class SingleStoreTransaction<\n\tTQueryResult extends SingleStoreQueryResultHKT,\n\tTPreparedQueryHKT extends PreparedQueryHKTBase,\n\tTFullSchema extends Record<string, unknown> = Record<string, never>,\n\tTSchema extends TablesRelationalConfig = Record<string, never>,\n> extends SingleStoreDatabase<TQueryResult, TPreparedQueryHKT, TFullSchema, TSchema> {\n\tstatic override readonly [entityKind]: string = 'SingleStoreTransaction';\n\n\tconstructor(\n\t\tdialect: SingleStoreDialect,\n\t\tsession: SingleStoreSession,\n\t\tprotected schema: RelationalSchemaConfig<TSchema> | undefined,\n\t\tprotected readonly nestedIndex: number,\n\t) {\n\t\tsuper(dialect, session, schema);\n\t}\n\n\trollback(): never {\n\t\tthrow new TransactionRollbackError();\n\t}\n\n\t/** Nested transactions (aka savepoints) only work with InnoDB engine. */\n\tabstract override transaction<T>(\n\t\ttransaction: (tx: SingleStoreTransaction<TQueryResult, TPreparedQueryHKT, TFullSchema, TSchema>) => Promise<T>,\n\t): Promise<T>;\n}\n\nexport interface PreparedQueryHKTBase extends SingleStorePreparedQueryHKT {\n\ttype: SingleStorePreparedQuery<Assume<this['config'], SingleStorePreparedQueryConfig>>;\n}\n","sourceCodeStart":241,"sourceCodeEnd":271,"githubUrl":"https://github.com/drizzle-team/drizzle-orm/blob/b7862528fd8fc39bc2653a6c18dad7c1f4e68d10/drizzle-orm/src/singlestore-core/session.ts#L241-L271","documentation":"TransactionRollbackError (message 'Rollback') thrown by SingleStoreTransaction.rollback() at session.ts:259. This is the documented mechanism to abort a transaction: calling tx.rollback() inside the transaction callback unwinds the transaction so the driver issues a ROLLBACK. It is intentional control flow, not an unexpected fault.","triggerScenarios":"Inside db.transaction(async (tx) => { ... tx.rollback(); }), typically after a domain rule violation or business-logic check that should void the unit of work; also thrown by nested savepoint rollback.","commonSituations":"Multi-step writes where a later validation fails and earlier writes must be undone; intentional abort on conflicting concurrent state; tests that verify rollback behavior.","solutions":["Catch TransactionRollbackError around the db.transaction call to treat it as an expected abort rather than a crash.","Ensure business-logic aborts call tx.rollback() and nothing else throws raw errors for the same purpose.","Do not swallow the error silently; log/handle it according to your rollback semantics."],"exampleFix":"// before\nawait db.transaction(async (tx) => {\n  await tx.insert(users).values(payload);\n  if (!valid) tx.rollback();\n});\n// after\ntry {\n  await db.transaction(async (tx) => {\n    await tx.insert(users).values(payload);\n    if (!valid) tx.rollback();\n  });\n} catch (e) {\n  if (e instanceof TransactionRollbackError) { /* expected abort */ }\n  else throw e;\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"import { TransactionRollbackError } from 'drizzle-orm/errors';\nfunction isRollback(e): e is TransactionRollbackError { return e instanceof TransactionRollbackError; }","tryCatchPattern":"import { TransactionRollbackError } from 'drizzle-orm/errors';\ntry {\n  await db.transaction(async (tx) => { if (!ok) tx.rollback(); });\n} catch (e) {\n  if (e instanceof TransactionRollbackError) { /* expected */ return; }\n  throw e;\n}","preventionTips":["Always wrap db.transaction in try/catch to handle intentional rollbacks.","Use tx.rollback() as the sole mechanism to abort a unit of work.","Do not let other accidental exceptions masquerade as rollbacks."],"tags":["transaction","rollback","singlestore","control-flow"],"analyzedSha":"b7862528fd8fc39bc2653a6c18dad7c1f4e68d10","analyzedAt":"2026-08-03T18:11:14.318Z","schemaVersion":2}