2023-02-27-TIL
2023-02-27-TIL
Today I Learned
Kotlin Functional Programming Framework
Arrow는 Kotlin에서 함수형 스타일로 코드를 쓰도록 돕는 라이브러리 모음이다. 공식 사이트는 타입이 있는 에러 처리, 코루틴 기반 동시성과 자원 관리, 회복성(resilience), 불변 데이터를 다루는 옵틱스, 컬렉션과 함수 확장을 주요 기능으로 든다(Arrow). 가장 먼저 접하는 것은 에러 처리다. 예외를 던지는 대신 Either<Error, Value>처럼 실패 가능성을 반환 타입에 드러내면, 호출하는 쪽이 실패를 처리하지 않고 넘어갈 수 없다.
- https://arrow-kt.io/
RabbitMQ Transaction
RabbitMQ는 AMQP 0-9-1의 트랜잭션(tx.select, tx.commit, tx.rollback)을 지원하지만, 데이터베이스 트랜잭션과 같은 보장을 기대하면 안 된다. 공식 문서에 따르면 AMQP는 트랜잭션이 큐 하나에만 관련될 때만 원자성을 보장하고, 여러 큐가 얽힌 상태에서 tx.commit 도중 브로커가 죽으면 일부 큐에만 결과가 반영될 수 있다. 문서는 RabbitMQ의 트랜잭션을 ACID라기보다 일괄 처리(batching) 기능에 가깝다고 표현한다(RabbitMQ: Semantics).
성능 문제도 있다. 메시지가 브로커에 안전하게 도착했는지 확인하려고 트랜잭션을 쓰면 처리량이 250분의 1로 떨어질 수 있다고 문서는 설명한다. 그래서 RabbitMQ는 같은 목적에 publisher confirms를 권한다. 브로커가 메시지를 받으면 비동기로 확인(ack)을 돌려주는 방식이다(RabbitMQ: Consumer Acknowledgements and Publisher Confirms).
- https://www.waitingforcode.com/rabbitmq/transactions-in-rabbitmq/read
- https://documentation.softwareag.com/onlinehelp/Rohan/num10-3/10-3_UM_webhelp/index.html#page/um-webhelp/co-amqp_transactions.html
- https://subscription.packtpub.com/book/application-development/9781849516501/1/ch01lvl1sec20/messaging-with-transactions
Distributed Tracing vs OpenTelemetry
두 용어는 비교 대상이라기보다 개념과 도구의 관계다. 분산 추적(distributed tracing)은 요청 하나가 여러 서비스를 거쳐 가는 경로를 기록하는 기법이다. OpenTelemetry 문서는 트레이스를 애플리케이션을 지나는 요청의 경로로 정의하고, 트레이스는 작업 단위인 스팬(span)들로 이루어진다. 서비스 경계를 넘을 때 트레이스 정보를 헤더 등에 실어 보내는 것을 컨텍스트 전파(context propagation)라고 하며, 이것이 있어야 서로 다른 프로세스의 스팬이 하나의 트레이스로 묶인다(OpenTelemetry: Traces).
OpenTelemetry는 트레이스, 메트릭, 로그 같은 텔레메트리 데이터를 생성하고 수집하고 내보내기 위한 벤더 중립 프레임워크다. 문서는 OpenTelemetry 자체가 관측 백엔드가 아니라고 분명히 적는다(What is OpenTelemetry?). 즉 OpenTelemetry로 계측해서 데이터를 만들고, 저장과 시각화는 Jaeger나 상용 APM 같은 백엔드가 맡는다.
- https://www.meshiq.com/what-is-distributed-tracing-vs-opentelemetry/
Soft Delete in Hibernate
소프트 삭제(soft delete)는 행을 실제로 지우지 않고 deleted 같은 플래그만 바꿔 삭제된 것처럼 다루는 방식이다. Hibernate에서는 @SQLDelete로 엔티티 삭제 시 실행할 SQL을 UPDATE로 바꾸고, @Where로 엔티티와 컬렉션을 조회할 때 삭제되지 않은 행만 읽도록 SQL 조건을 붙인다(Hibernate User Guide 5.6: @Where, Custom CRUD).
1
2
3
4
@Entity
@SQLDelete(sql = "UPDATE post SET deleted = true WHERE id = ?")
@Where(clause = "deleted = false")
public class Post { ... }
링크한 글은 여기에 ID로 단건을 조회하는 경로까지 필터링하는 방법과, 연관 컬렉션에서 삭제된 자식을 숨기는 방법을 다룬다. 주의할 점은 행이 실제로 남아 있으므로 유니크 제약도 삭제된 행에 그대로 걸린다는 것이다. 같은 이메일로 다시 가입하는 경우처럼 삭제 후 같은 값을 다시 쓰는 요구가 있다면 제약 설계를 함께 바꿔야 한다.
- https://vladmihalcea.com/the-best-way-to-soft-delete-with-hibernate/
댓글
아직 댓글이 없습니다