Files
zellyy-finance/src/utils/sync/transaction/deleteTransaction.ts
hansoo 58355c3936 트랜잭션 삭제 기능 성능 및 안정성 개선
1. UI와 서버 작업 완전 분리하여 응답성 향상
2. AbortController를 이용한 Supabase 타임아웃 처리 구현
3. requestAnimationFrame 및 queueMicrotask 활용한 비동기 최적화
4. 메모리 누수 방지를 위한 pendingDeletion 상태 관리 개선
5. 타입 안전성 향상 (any 타입 제거)

트랜잭션 삭제 시 앱 먹통 현상 해결
2025-03-18 16:14:15 +09:00

70 lines
2.4 KiB
TypeScript

import { supabase } from '@/lib/supabase';
import { isSyncEnabled } from '../syncSettings';
import { toast } from '@/hooks/useToast.wrapper';
/**
* 특정 트랜잭션 ID 삭제 처리 - 완전히 재구현된 안정성 개선 버전
* 타임아웃 처리 및 오류 회복력 강화
*/
export const deleteTransactionFromServer = async (userId: string, transactionId: string): Promise<void> => {
if (!isSyncEnabled()) return;
try {
console.log(`트랜잭션 삭제 요청: ${transactionId}`);
// AbortController를 사용한 타임아웃 처리 (3초)
const controller = new AbortController();
const timeoutId = setTimeout(() => {
console.warn(`트랜잭션 삭제 타임아웃 (ID: ${transactionId})`);
controller.abort();
}, 3000);
try {
// Supabase 요청에 AbortSignal 추가
const { error } = await supabase
.from('transactions')
.delete()
.eq('transaction_id', transactionId)
.eq('user_id', userId)
.abortSignal(controller.signal);
// 요청 완료 후 타임아웃 해제
clearTimeout(timeoutId);
if (error) {
console.error('트랜잭션 삭제 실패:', error);
throw error;
}
console.log(`트랜잭션 ${transactionId} 삭제 완료`);
} catch (e) {
// 타임아웃에 의한 중단인 경우
const error = e as Error & { code?: number };
if (error.name === 'AbortError' || error.code === 20) {
console.warn(`트랜잭션 삭제 요청 타임아웃 (ID: ${transactionId})`);
return; // 정상적으로 처리된 것으로 간주
}
throw error; // 그 외 오류는 상위로 전파
} finally {
clearTimeout(timeoutId); // 안전하게 항상 타임아웃 해제
}
} catch (error) {
console.error('트랜잭션 삭제 중 오류:', error);
// 시각적 알림은 최소화 (사용자 경험 저하 방지)
// 개발 모드나 로그에만 오류 기록
if (process.env.NODE_ENV === 'development') {
toast({
title: "동기화 문제",
description: "서버에서 삭제 중 문제가 발생했습니다. 로컬 데이터는 정상 처리되었습니다.",
variant: "default",
duration: 1500
});
}
// UI 작업에는 영향을 주지 않도록 오류 무시
console.log('서버 동기화 오류 발생했으나 UI 작업은 계속 진행됨');
}
};