Hibernate-reactive: ν–₯상 - spring @Transactional μ£Όμ„κ³Όμ˜ 톡합

에 λ§Œλ“  2021λ…„ 05μ›” 20일  Β·  16μ½”λ©˜νŠΈ  Β·  좜처: hibernate/hibernate-reactive

μ•ˆλ…•,

μš°λ¦¬λŠ” postgres-db+spring boot+spring data+r2dbc둜 κ΅¬μ„±λœ ν˜„μž¬ μ†Œν”„νŠΈμ›¨μ–΄ μ†Œν”„νŠΈμ›¨μ–΄λ₯Ό λŒ€μ²΄ν•˜κΈ° μœ„ν•΄ μ΅œλŒ€ μ ˆμ „ λͺ¨λ“œ λ°˜μ‘μ„ μ§€μ†μ μœΌλ‘œ ν‰κ°€ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€. μš°λ¦¬λŠ” r2dbcλ₯Ό μ‚¬μš©ν•˜μ—¬ λ§Žμ€ μ œν•œμ— μ§λ©΄ν–ˆκ³  Hibernate에 λŒ€ν•΄ 이미 가지고 μžˆλŠ” λ§Žμ€ 지식을 μž¬μ‚¬μš©ν•˜κ³  μ‹Άμ—ˆμŠ΅λ‹ˆλ‹€.
μš°λ¦¬λŠ” 전체 마이크둜 μ„œλΉ„μŠ€λ₯Ό 거의 λ¦¬νŒ©ν† λ§ν•˜κ³  자체 μŠ€ν”„λ§ 데이터(일반 리포지토리)λ₯Ό λ‹€μ‹œ μž‘μ„±ν–ˆμœΌλ©° 정말 μ’‹μ•„ λ³΄μž…λ‹ˆλ‹€.

κ°œλ°œμžκ°€ ν”„λ‘œκ·Έλž˜λ° 방식 λŒ€μ‹  선언적 νŠΈλžœμž­μ…˜ 관리(주석 μ‚¬μš©)λ₯Ό μ‚¬μš©ν•˜λŠ” μ˜΅μ…˜μ—μ„œ μ œκΈ°ν•˜λŠ” μ£Όμš” 문제 쀑 ν•˜λ‚˜μž…λ‹ˆλ‹€.

μš°λ¦¬λŠ” κ·ΈλŸ¬ν•œ λ©”μ»€λ‹ˆμ¦˜μ„ κ΅¬ν˜„ν•˜λŠ” 것이 Hibernate Reactive의 λͺ©μ μ΄ μ•„λ‹ˆλΌ ν‘œμ€€ Hibernate에 λŒ€ν•΄ μˆ˜ν–‰λœ κ²ƒμ²˜λŸΌ Hibernate와 ν†΅ν•©λ˜λŠ” ν”„λ ˆμž„μ›Œν¬(Spring, Quarkus...)에 λŒ€ν•œ κ²ƒμž„μ„ μ•Œκ³  μžˆμŠ΅λ‹ˆλ‹€. μš°λ¦¬κ°€ 직접 ν•˜κ³  싢어도 Hibernate Reactive의 νŠΈλžœμž­μ…˜ APIλŠ” ν‘œμ€€ Hibernate API와 같지 μ•Šκ³  νŠΈλžœμž­μ…˜ κ΄€λ¦¬μžμ™€ μƒν˜Έ μž‘μš©ν•  APIκ°€ μ—†μŠ΅λ‹ˆλ‹€.

이에 λŒ€ν•œ κ·€ν•˜μ˜ μ˜κ²¬μ„ 얻을 수 있고 (ν•  수 μžˆλŠ” 경우 더 λ§Žμ€ :smiley:), 그리고 μ—¬μ „νžˆ 일반적인 지침을 μ œμ•ˆν•˜κΈ° μœ„ν•΄ ν•  수 μžˆλ‹€κ³  μƒκ°ν•œλ‹€λ©΄ ν˜„μž¬λ‘œμ„œλŠ” μ–΄λ–»κ²Œ ν•΄μ•Ό ν•˜λŠ”μ§€μ— λŒ€ν•œ λ‹¨μ„œκ°€ μ—†κΈ° λ•Œλ¬Έμ— μ €λŠ” 기쁠 κ²ƒμž…λ‹ˆλ‹€.
감사 ν•΄μš”

problem

λͺ¨λ“  16 λŒ“κΈ€

Springμ—λŠ” 인터셉터λ₯Ό bean λ©”μ†Œλ“œ ν˜ΈμΆœμ— λ°”μΈλ”©ν•˜κΈ° μœ„ν•΄ 주석을 μ‚¬μš©ν•  수 μžˆλŠ” μΌμ’…μ˜ 인터셉터 κ°œλ…μ΄ μžˆλ‹€κ³  κ°€μ •ν•©λ‹ˆλ‹€. 이와 같이 인터셉터 λ‚΄μ—μ„œ withTransaction() λ₯Ό ν˜ΈμΆœν•œ λ‹€μŒ Bean λ©”μ†Œλ“œμ— μœ„μž„ν•˜λ©΄ 선언적 νŠΈλžœμž­μ…˜ 관리가 μ „λΆ€μž…λ‹ˆλ‹€. μ‹€μ œλ‘œλŠ” λͺ‡ μ€„μ˜ μ½”λ“œλ§Œ 있으면 λ©λ‹ˆλ‹€. (적어도 그것은 CDI에 μžˆμ„ κ²ƒμž…λ‹ˆλ‹€. λ‚˜λŠ” 봄에 λŒ€ν•΄ 덜 ν™•μ‹ ν•©λ‹ˆλ‹€.)

μœ μΌν•œ λ―Έλ¬˜ν•¨μ€ ν˜„μž¬ λ°˜μ‘ μŠ€νŠΈλ¦Όμ— 이미 λ°”μΈλ”©λœ νŠΈλžœμž­μ…˜μ΄ μžˆλŠ”μ§€ κ°μ§€ν•˜λŠ” 방법이 ν•„μš”ν•˜λ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€. 우리 μŠ€νƒμ—μ„œλŠ” MP μ»¨ν…μŠ€νŠΈλ₯Ό μ‚¬μš©ν•˜μ—¬ μˆ˜ν–‰λ©λ‹ˆλ‹€. 그것이 Spring Landμ—μ„œ μ–΄λ–»κ²Œ μˆ˜ν–‰λ˜λŠ”μ§€ μ „ν˜€ λͺ¨λ¦…λ‹ˆλ‹€.

(OTOH XA νŠΈλžœμž­μ…˜ κ΄€λ¦¬μžμ™€ ν†΅ν•©ν•˜λŠ” 방법에 λŒ€ν•΄ λ¬»λŠ”λ‹€λ©΄ κΈ€μŽ„μš”, 그것은 μ™„μ „νžˆ λ‹€λ₯Έ μ›œ 캔이며 ν˜„μž¬ λ°˜μ‘ λ“œλΌμ΄λ²„μ™€ μ‹€μ œλ‘œ μ‹€μš©μ μ΄μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. μš°λ¦¬λŠ” 아직 μ§„μ •ν•œ λ°˜μ‘ νŠΈλžœμž­μ…˜μ΄ μ—†μŠ΅λ‹ˆλ‹€. κ΄€λ¦¬μž.)

μ§€κΈˆμ€ λΆ„μ‚° νŠΈλžœμž­μ…˜μ΄ ν•„μš”ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

그러면 SessionFactory.withTransaction() λ₯Ό ν˜ΈμΆœν•˜λŠ” 인터셉터가 μ œλŒ€λ‘œ μž‘λ™ν•΄μ•Ό ν•©λ‹ˆλ‹€.

이 방법을 μ‹œλ„ν•˜κ³  μ—…λ°μ΄νŠΈν•©λ‹ˆλ‹€. 감사 ν•΄μš”

@gavinking Spring은 Aspectλ₯Ό μ‚¬μš©ν•˜μ—¬ @Transactional 을 κ΅¬ν˜„ν•˜λŠ” κ²ƒμœΌλ‘œ λ³΄μž…λ‹ˆλ‹€. 그닀지 μ€‘μš”ν•˜μ§€λŠ” μ•Šμ§€λ§Œ κ΅¬ν˜„ν•˜λŠ” 것이 더 간단할 μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€.
ν•˜μ§€λ§Œ openSession() 및 closeSession() APIκ°€ μžˆμœΌλ―€λ‘œ Stage ν΄λž˜μŠ€μ—μ„œ openTransaction() commitTransaction() 및 rollbackTransaction()에 λŒ€ν•œ APIλ₯Ό λ…ΈμΆœν•˜λŠ” κ²½μš°μ—λ§Œ ν•  수 μ—†λ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€. νŠΈλžœμž­μ…˜ κ°œμ²΄κ°€ ν•„μš”ν•˜κ³  withTransaction이 μΆ©λΆ„ν•˜μ§€ μ•Šλ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€.
말이 λ©λ‹ˆκΉŒ?

λž©ν•‘ν•˜κ³  λ©”μ„œλ“œλ‘œ 전달할 수 μžˆλŠ” "μ£Όλ³€" 인터셉터에 λŒ€ν•œ μΌμ’…μ˜ κ°œλ…μ΄ μžˆμ–΄μ•Ό ν•©λ‹ˆλ‹€.

(before/after μΈν„°μ…‰ν„°λ‘œλŠ” ν•  수 μ—†λŠ” 것이 μ‚¬μ‹€μž…λ‹ˆλ‹€.)

λ‚˜λŠ” 이것이 ν•˜λ‚˜λΌκ³  μƒκ°ν•œλ‹€: https://howtodoinjava.com/spring-aop/aspectj-around-annotation-example/

@gavinking "MP μ»¨ν…μŠ€νŠΈλ₯Ό μ‚¬μš©ν•˜μ—¬ μˆ˜ν–‰ν•  μŠ€νƒμ—μ„œ" 전에 μž‘μ„±ν•œ λ‚΄μš©μ— λŒ€ν•΄ μžμ„Ένžˆ μ„€λͺ…ν•΄ μ£Όμ‹œκ² μŠ΅λ‹ˆκΉŒ? νŠΈλžœμž­μ…˜μ΄ ν˜„μž¬ μŠ€νŠΈλ¦Όμ— 이미 λ°”μΈλ”©λ˜μ–΄ μžˆλŠ”μ§€ ν™•μΈν•˜λ €λ©΄? μž‘μ„±ν•œ μ½”λ“œλ‚˜ ν…ŒμŠ€νŠΈλ₯Ό μ°Έμ‘°ν•  수 μžˆμŠ΅λ‹ˆκΉŒ? μ„Έμ…˜μ— λŒ€ν•΄μ„œλ„ λ§ˆμ°¬κ°€μ§€μž…λ‹ˆλ‹€. μ„Έμ…˜μ΄ ν˜„μž¬ μŠ€νŠΈλ¦Όμ—μ„œ 이미 μ—΄λ € μžˆλ‹€λŠ” 것을 μ–΄λ–»κ²Œ 이해할 수 μžˆμŠ΅λ‹ˆκΉŒ?
감사 ν•΄μš”.

봄에 μ–΄λ–»κ²Œ ν•˜λŠ”μ§€ λͺ¨λ₯΄κ² μ–΄μš”. threadlocalκ³Ό λΉ„μŠ·ν•˜μ§€λ§Œ μŠ€λ ˆλ“œ λŒ€μ‹  ν˜„μž¬ λ°˜μ‘ μŠ€νŠΈλ¦Όμ— 둜컬 λ°”μΈλ”©λœ μΌμ’…μ˜ ꡬ성이 ν•„μš”ν•©λ‹ˆλ‹€. λ‚˜λŠ” κ·Έλ“€μ—κ²Œ λ­”κ°€κ°€ μžˆμ–΄μ•Όν•œλ‹€κ³  ν™•μ‹ ν•©λ‹ˆλ‹€.

λ‚˜λŠ” ν˜„μž¬ spring @Transactional 을 μ‚¬μš©ν•˜μ§€ μ•Šμ„ κ²ƒμ΄μ§€λ§Œ Spring에 λŒ€ν•΄ λ„ˆλ¬΄ 깊이 λ“€μ–΄κ°€λŠ” 것을 ν”Όν•˜κΈ° μœ„ν•΄ 우리 μžμ‹ μ˜ νŠΈλžœμž­μ…˜ 주석을 κ΅¬ν˜„ν•©λ‹ˆλ‹€. κ·Έλž˜μ„œ λ‚΄ 이전 μ§ˆλ¬Έμ€ "MP μ»¨ν…μŠ€νŠΈλ₯Ό μ‚¬μš©ν•˜μ—¬ μˆ˜ν–‰ν•  μŠ€νƒμ—μ„œ"λΌλŠ” λ¬Έμž₯κ³Ό 관련이 μžˆμŠ΅λ‹ˆλ‹€.

"우리 μŠ€νƒ" == Quarkus.

Spring ν™˜κ²½μ—μ„œ λΉ„μŠ·ν•œ 것을 μ°Ύμ•„μ•Ό ν•œλ‹€κ³  λ§ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.

값을 ν˜„μž¬ λ°˜μ‘ μŠ€νŠΈλ¦Όμ— 바인딩할 수 μ—†λ‹€λ©΄ 선언적 νŠΈλžœμž­μ…˜μ„ κ°€μ§ˆ 수 μ—†κ³  κ°„λ‹¨ν•˜κ²Œ νŠΈλžœμž­μ…˜μ„ "μˆ˜λ™μœΌλ‘œ" 관리해야 ν•˜κΈ° λ•Œλ¬Έμž…λ‹ˆλ‹€. ( withTransaction() λ₯Ό ν˜ΈμΆœν•˜λ©΄ μ‹€μ œλ‘œ 맀우 κ°„λ‹¨ν•©λ‹ˆλ‹€. μ‚¬λžŒλ“€μ΄ μ™œ 주석이 ν•„μš”ν•˜λ‹€κ³  μƒκ°ν•˜λŠ”μ§€ λͺ¨λ₯΄κ² μŠ΅λ‹ˆλ‹€.)

ν•˜μ§€λ§Œ μ–΄λ–»κ²Œλ“  ν•  수 μžˆλŠ” 방법이 μžˆμ–΄μ•Ό ν•œλ‹€κ³  ν™•μ‹ ν•©λ‹ˆλ‹€. 당신은 단지 잘λͺ»λœ μ‚¬λžŒμ—κ²Œ 묻고 μžˆμŠ΅λ‹ˆλ‹€.

이런 것일 μˆ˜λ„ μžˆμ§€λ§Œ μ €λŠ” 정말 λͺ¨λ¦…λ‹ˆλ‹€ https://projectreactor.io/docs/core/3.4.0-M1/api/index.html?reactor/util/context/Context.html

μ•„λ§ˆλ„ 이것은? https://www.baeldung.com/spring-transaction-active

마감: #782둜 λŒ€μ²΄λ¨.

@yaakov-berkovitch와 ν•¨κ»˜ #779λ₯Ό μ‚¬μš©ν•˜μ—¬ 이 μž‘μ—…μ„ κ΅¬ν˜„ν•˜λŠ” 것이 훨씬 더 μ‰¬μšΈ κ²ƒμž…λ‹ˆλ‹€.

@gavinking κ°μ‚¬ν•©λ‹ˆλ‹€!!

이 νŽ˜μ΄μ§€κ°€ 도움이 λ˜μ—ˆλ‚˜μš”?
0 / 5 - 0 λ“±κΈ‰