MCPcopy
hub / github.com/CodebuffAI/codebuff / withSerializableTransaction

Function withSerializableTransaction

packages/internal/src/db/transaction.ts:176–235  ·  view source on GitHub ↗
({
  callback,
  context = {},
  logger,
}: {
  callback: TransactionCallback<T>
  context: Record<string, unknown>
  logger: Logger
})

Source from the content-addressed store, hash-verified

174 * @returns The result of the transaction
175 */
176export async function withSerializableTransaction<T>({
177 callback,
178 context = {},
179 logger,
180}: {
181 callback: TransactionCallback<T>
182 context: Record<string, unknown>
183 logger: Logger
184}): Promise<T> {
185 return withRetry(
186 async () => {
187 return await db.transaction(callback, { isolationLevel: 'serializable' })
188 },
189 {
190 maxRetries: 5, // Allow more retries for connection errors to recover
191 retryDelayMs: INITIAL_RETRY_DELAY, // 1s, 2s, 4s, 8s, 16s exponential backoff
192 retryIf: (error) => {
193 // Only determine if error is retryable; logging happens in onRetry
194 return getRetryableErrorDescription(error) !== null
195 },
196 onRetry: (error, attempt) => {
197 const errorCode = getPostgresErrorCode(error) ?? 'unknown'
198 const errorDescription =
199 getRetryableErrorDescription(error) ?? 'unknown'
200 // Calculate cumulative retry delay: 1s + 2s + 4s + ... (geometric series)
201 const cumulativeDelayMs = INITIAL_RETRY_DELAY * (Math.pow(2, attempt) - 1)
202
203 // Only log at WARN level after significant cumulative delay to avoid excessive logging
204 // First few quick retries are expected behavior; extended retries indicate real issues
205 if (cumulativeDelayMs >= SIGNIFICANT_RETRY_DELAY_MS) {
206 logger.warn(
207 {
208 ...context,
209 attempt,
210 pgErrorCode: errorCode,
211 pgErrorDescription: errorDescription,
212 cumulativeDelayMs,
213 },
214 `Serializable transaction retry ${attempt}: ${errorDescription} (${errorCode}), cumulative delay ${(cumulativeDelayMs / 1000).toFixed(1)}s`,
215 )
216
217 // Track in PostHog for analytics
218 trackEvent({
219 event: AnalyticsEvent.TRANSACTION_RETRY_THRESHOLD_EXCEEDED,
220 userId: getUserIdForAnalytics(context),
221 properties: {
222 ...context,
223 transactionType: 'serializable',
224 attempt,
225 pgErrorCode: errorCode,
226 pgErrorDescription: errorDescription,
227 cumulativeDelayMs,
228 },
229 logger,
230 })
231 }
232 },
233 },

Callers 1

Calls 5

withRetryFunction · 0.90
trackEventFunction · 0.90
getPostgresErrorCodeFunction · 0.85
getUserIdForAnalyticsFunction · 0.85

Tested by

no test coverage detected