Tiny Star

IT 12

[SpringBoot/JSP] 다국어 처리

한영 변환 기능 관련 얘기가 나왔다. 내가 하게 되는지는 확정되지 않았지만...예전에 타임리프 태그로는 언어 변환을 해본 적이 있다. 반면 JSP에서는 해본 적이 없어서 이번 기회에 정리해보려고 한다. 이번에는 단순히 한/영만 고려하지 않고, 확장성을 위해 다국어로 생각해봤다.일단 간단하게 떠올려본 방식은 아래 네 가지다. 1. properties에 정리하고 JSTL `` 태그로 변환 (예: `message_ko.properties`, `message_en.properties`) 2. 언어별 별도 데이터베이스 사용 (예: `mariadb://../project1_kr`, `mariadb://../project1_en`) 3. 언어별 별도 테이블 분리 (예: `project.table1_kr`, `proj..

IT 2025.08.08

[Spring Batch] Cursor vs Paging

Spring Batch를 사용해 대용량 데이터를 처리할 때 가장 먼저 고민해야 할 것은 데이터를 어떻게 읽을 것인가라고 생각한다.이때 많이 사용되는 두 가지 방식이 바로 Cursor 기반과 Paging 기반인데, 두 방식의 동작 방식, 장단점을 정리해봤다. 1. Cursor 기반JDBC의 ResultSet을 활용하여, DB에서 쿼리 1번으로 결과셋을 열어두고, 그 결과를 한 줄씩 순차적으로 읽는 방식 동작 방식`JdbcCursorItemReader`가 쿼리를 단 1번 실행DB는 결과를 계산한 뒤 커서(cursor) 를 열고 기다림Spring Batch가 `read()`를 호출할 때마다 한 줄씩 커서를 통해 받아옴메모리에는 항상 1~2개의 row만 존재@Beanpublic JdbcCursorItemRea..

IT 2025.07.25

[Spring] @Transactional 이 일어나지 않는 경우

"트랜잭션이 일어나지 않는 경우"에 대해서 설명해달라는 질문을 받았다.트랜잭션 메서드 안에 트랜잭션 메서드가 있는 경우에는 작동하지 않는다는 건 알고 있었는데, 알고 있는 것조차 대답을 못할정도로 충분히 숙지되어있지 않다는 걸 느껴 다시금 정리해보려고 한다. 1. 자기 자신을 호출하는 경우 (self-invocation)@Servicepublic class MyService { @Transactional public void methodA() { this.methodB(); // 프록시를 거치지 않아 @Transactional 무시됨 } @Transactional public void methodB() { userRepository.save(new U..

IT 2025.07.23

[Cloudflare Tunnel] 우리집 IP 노출 없이 노트북을 연결해보자

왜 Cloudflare Tunnel을 알아보게 되었을까?처음에는 Oracle Cloud Free Tier로 서버를 구성해보려 했다. 하지만 예상치 못한 문제가 있었는데, "Out of host capacity" 에러가 2주 넘게 지속되면서, 언제쯤 VM을 생성할 수 있을지 알 수 없었기 때문에 마냥 기다릴 수만은 없었다. [관련 글 보기]그래서 대안을 고민하다가, 내부 서버를 직접 구축해보기로 했다. 라즈베리파이도 고려했지만 추가 비용이 들어 부담이 되었고, 결국 기존에 사용하던 노트북을 서버로 활용해보기로 했다.하지만 여기에도 문제는 있었는데, 외부에서 접속하려면 내부 IP를 노출하고 포트를 개방해야 하기 때문에 보안 측면에서 불안했다.그러던 중 Cloudflare Tunnel을 알게 되었고, 이걸 이..

IT 2025.07.16

[Oracle Cloud] 인스턴스 생성 자동화 (Out of host capacity)

나도 이제 최대 4CORE, 24RAM 무료 인스턴스를 생성할 수 있다는 설레는 마음으로 생성을 시도했다. Out of capacity for shape VM.Standard.A1.Flex in availability domain AD-1. Create the instance in a different availability domain or try again later.If you specified a fault domain, try creating the instance without specifying a fault domain. If that doesn’t work, please try again later.Learn more about host capacity.헛된 꿈이었음을...싱가포르(가입 ..

IT 2025.07.03

[Oracle Cloud] 오라클 클라우드 프리티어(Free Tier) 가입

서버를 구성하기 위해 가장 많이 알려진건 AWS 무료티어라고 생각한다. 옛날기억으로는 잘못된 설정으로 과금이 됐을지 온종일 조마조마하며 바라봤었다. 찾아보니 최근에도 과금되는 건 어쩔 수 없는 것 같다.알아보니 오라클 클라우드 무료티어는 설정에 따라 1~4대 서버를 제공하고 무료로 제공하는 것만 잘 체크하면 과금되는 일이 없는 것 같아서 사용해보기로 했다. 신중하게 도전하는 걸 추천한다. 필자는 이거저거 틀리고 계속 재시도하라고해서 다시했더니 너무 많은 시도로 막혔다. 몇 분뒤하면 되는데 다음 단계에서 또 시도횟수가 많다고 막히고... 얼마만큼의 간격으로 시도가 가능한지 모르므로 각 잡고 시도하자. 오라클 클라우드 무료 티어(Oracle Cloud Free Tier) 페이지에 접속해서 [무료로 시작하기..

IT 2025.07.02

[Spring Boot] 대용량 데이터 이관 JPA vs JDBC vs MyBatis 비교

대용량 이관 시 JPA vs JDBC vs MyBatis: 어떤 Writer를 선택할까?대용량 데이터를 처리하다 보면, 성능이 코드 구조보다 우선이 될 때가 많다. 이 글은 실제 테스트를 통해 JPA, JDBC, MyBatis 각각의 Writer 성능을 비교하고, 어떤 상황에 어떤 Writer를 선택하는 게 좋은지 정리한 기록이다. 비교 조건약 10만 건의 BookRating 데이터를 단순 insert동적 매핑이나 조건 분기 없음각 방식으로 동일한 데이터를 동일 조건으로 insert 테스트성능 기준: 실행 시간(ms) 기본 구조 공통적으로 사용하는 Entity는 다음과 같다.@Entity@Data@NoArgsConstructor@AllArgsConstructorpublic class BookRating..

IT 2025.06.27

[Spring Boot] Spring Security 추가 후 CORS/401/403 오류 해결

멀쩡하던 서비스에서 SpringSecurity 의존성을 추가하면 갑자기 프론트 요청이 막힌다.❌ fetch 요청 시 CORS 에러 발생 ❌ 응답은 갔는데도 403 Forbidden ❌ 로그인하지 않았는데 401 Unauthorized 이번 글에서는 Spring Security 추가 이후 발생하는 대표적인 API 통신 문제들을 왜 발생하는지, 그리고 어떻게 해결할 수 있는지 정리해보겠습니다. 문제 상황Spring Security를 추가한 직후, 아래와 같은 문제가 발생 증상 설명 CORS 오류브라우저에서 요청 자체가 막힘 (preflight 실패)401 UnauthorizedSpring Security가 로그인 안 했다고 거부403 Forbidden응답은 갔지만 CORS 헤더 누락으로 브라우저가 거부..

IT 2025.06.27

[데이터] Kaggle (캐글)

프로젝트에 활용할 데이터셋을 찾다가 Kaggle(캐글) 이라는 사이트를 알게되었다. Kaggle데이터 과학자와 머신러닝 엔지니어들이 모여 서로 문제를 풀고, 데이터를 분석하고, 학습하는 플랫폼Kaggle은 수십만 개의 데이터를 자유롭게 검색하고 활용할 수 있는 데이터 저장소 제공CSV부터 이미지, JSON까지 다양한 형식의 데이터셋이 있고, 무료로 이용 가능 데이터셋 예시 주제 예시 데이터셋 건강/의료코로나 확진자 현황, 의학 이미지스포츠월드컵 경기 결과, NBA 선수 스탯경제/금융주식 시장, 암호화폐 가격게임포켓몬 정보, 롤 챔피언 통계일상/기타넷플릭스 영화 목록, 음식 영양 정보 ⭐ 실제 업무용 데이터뿐만 아니라, 흥미로운 주제의 캐주얼한 데이터도 많아서 초보자도 쉽게 접근 가능 사용하는 법 ..

IT 2025.05.05

[Spring] @Transactional 트랜잭션 어노테이션

쿠폰 프로젝트를 진행하면서 사용하게 된 어노테이션이다. [클라이언트 요청] ↓POST /api/admin/coupons ↓[CouponService] ↓1. couponsRepository.save(coupon) 실행 ↓2. RedisTemplate 재고 등록Redis에 재고 등록을 하게되는데, 만약 이 때 오류로 Redis 등록에 실패했다면 DB에 저장된 데이터도 삭제하는게 좋다고 판단했다. 왜냐면 실패했을 시 똑같은 쿠폰을 다시 발행할텐데, DB 에는 동일한 이름의 쿠폰이 두 개가 등록되기 때문이다. 1. @Transactional@Transactional은 메서드 실행을 하나의 트랜잭션 단위로 묶어서,전체가 성공하면 커밋(commit),중간에 실패하면 롤백(rollback) 하게..

IT 2025.04.28
top