Post

Transactional Annotation๊ณผ Proxy


@Transactional์€ ๋ฉ”์„œ๋“œ ์‹คํ–‰ ์ „ํ›„์— ํŠธ๋žœ์žญ์…˜์„ ์‹œ์ž‘ํ•˜๊ณ  ์ปค๋ฐ‹ ๋˜๋Š” ๋กค๋ฐฑํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋Š” ์–ด๋…ธํ…Œ์ด์…˜์œผ๋กœ ์Šคํ”„๋ง์—์„œ ํŠธ๋žœ์žญ์…˜ ๊ด€๋ฆฌ๋ฅผ ์ž๋™์œผ๋กœ ์ฒ˜๋ฆฌํ•œ๋‹ค.


ํŠธ๋žœ์žญ์…˜ ๊ฒฝ๊ณ„ ์„ค์ •

  • ํŠธ๋žœ์žญ์…˜ ์‹œ์ž‘:
    • @Transactional์ด ์ ์šฉ๋œ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ, ๋จผ์ € PlatformTransactionManager๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํŠธ๋žœ์žญ์…˜์„ ์‹œ์ž‘ํ•œ๋‹ค.
    • ํŠธ๋žœ์žญ์…˜ ๋ฉ”๋‹ˆ์ €๋Š” ํŠธ๋žœ์žญ์…˜ ๊ฒฝ๊ณ„๋ฅผ ์„ค์ •ํ•˜๊ณ , ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€์˜ ์—ฐ๊ฒฐ์„ ํŠธ๋žœ์žญ์…˜ ๋ชจ๋“œ๋กœ ์ „ํ™˜๋‹ค.
    • ์ด๋ฅผ ํ†ตํ•ด ํ•ด๋‹น ๋ฉ”์„œ๋“œ๊ฐ€ ํŠธ๋žœ์žญ์…˜ ๋‚ด์—์„œ ์‹คํ–‰๋˜๋„๋ก ํ•œ๋‹ค.
  • ํŠธ๋žœ์žญ์…˜ ์ปค๋ฐ‹:
    • ๋ฉ”์„œ๋“œ๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ์™„๋ฃŒ๋˜๋ฉด TransactionManager๋Š” ํŠธ๋žœ์žญ์…˜์„ ์ปค๋ฐ‹ํ•œ๋‹ค.
  • ํŠธ๋žœ์žญ์…˜ ๋กค๋ฐฑ:
    • ๋ฉ”์„œ๋“œ ์‹คํ–‰ ์ค‘์— ์ฒดํฌ๋“œ ์˜ˆ์™ธ ์ด์™ธ์˜ ์˜ˆ์™ธ(๋Ÿฐํƒ€์ž„ ์˜ˆ์™ธ, ์˜ค๋ฅ˜)๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด TransactionManager๋Š” ํŠธ๋žœ์žญ์…˜์„ ๋กค๋ฐฑํ•œ๋‹ค.
    • ๊ธฐ๋ณธ์ ์œผ๋กœ Checked Exception๋Š” ๋กค๋ฐฑํ•˜ํ•˜์ง€ ์•Š๋Š”๋‹ค.
    • Runtime Exception, Error์€ ๋กค๋ฐฑ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.
    • ํ•˜์ง€๋งŒ ๊ฐœ๋ฐœ์žฆ๊ฐ€ ๋ช…์‹œ์ ์œผ๋กœ ์ง€์ •ํ•˜์—ฌ ์ฒดํฌ๋“œ ์˜ˆ์™ธ์— ๋กค๋ฐฑ์„ ๋ฐœ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.


ํŠธ๋žœ์žญ์…˜ ์†์„ฑ

@Transactional ์–ด๋…ธํ…Œ์ด์…˜์€ ๋‹ค์–‘ํ•œ ์†์„ฑ์„ ํ†ตํ•ด ํŠธ๋žœ์žญ์…˜์˜ ๋™์ž‘ ๋ฐฉ์‹์„ ์กฐ์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

  • propagation: ํŠธ๋žœ์žญ์…˜ ์ „ํŒŒ ๋ฐฉ์‹ (์˜ˆ: REQUIRED, REQUIRES_NEW ๋“ฑ)
  • isolation: ํŠธ๋žœ์žญ์…˜ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€ (์˜ˆ: READ_COMMITTED, SERIALIZABLE ๋“ฑ)
  • timeout: ํŠธ๋žœ์žญ์…˜์ด ์™„๋ฃŒ๋˜์–ด์•ผ ํ•˜๋Š” ์ตœ๋Œ€ ์‹œ๊ฐ„
  • readOnly: ์ฝ๊ธฐ ์ „์šฉ ํŠธ๋žœ์žญ์…˜ ์—ฌ๋ถ€
  • rollbackFor: ๋กค๋ฐฑํ•  ์˜ˆ์™ธ ํƒ€์ž…
  • noRollbackFor: ๋กค๋ฐฑํ•˜์ง€ ์•Š์„ ์˜ˆ์™ธ ํƒ€์ž…




Proxy

ํ”„๋ก์‹œ๋Š” ์‹ค์ œ ๊ฐ์ฒด๋ฅผ ๊ฐ์‹ธ์„œ, ํด๋ผ์ด์–ธํŠธ์™€ ์‹ค์ œ ๊ฐ์ฒด ์‚ฌ์ด์—์„œ ์ƒํ˜ธ์ž‘์šฉํ•œ๋‹ค.
์Šคํ”„๋ง์—์„œ ์ฃผ๋กœ ๋ฐ˜๋ณต๋˜๋Š” ๋ถ€๊ฐ€๊ธฐ๋Šฅ(๋กœ๊น…, ํŠธ๋žœ์žญ์…˜ ๊ด€๋ฆฌ, ๋ณด์•ˆ ๋“ฑ)์„ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋œ๋‹ค.

ํด๋ผ์ด์–ธํŠธ๋Š” ์‹ค์ œ ๊ฐ์ฒด๋ฅผ ์ง์ ‘ ํ˜ธ์ถœํ•˜์ง€ ์•Š๊ณ , ํ”„๋ก์‹œ ๊ฐ์ฒด๋ฅผ ํ†ตํ•ด ๊ฐ„์ ‘์ ์œผ๋กœ ํ˜ธ์ถœํ•˜์—ฌ, ๊ฐ์ฒด์— ๋Œ€ํ•œ ์ ‘๊ทผ์„ ์ œ์–ดํ•˜๊ณ  ๋ถ€๊ฐ€ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•œ๋‹ค.



Spring AOP๋Š” ํ”„๋ก์‹œ ํŒจํ„ด์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•œ๋‹ค.
@Transactional์€ Spring AOP์˜ ๋Œ€ํ‘œ์ ์ธ ์˜ˆ๋กœ, Proxy ํ˜•ํƒœ๋กœ ๋™์ž‘ํ•œ๋‹ค.

์Šคํ”„๋ง์—์„œ ํ”„๋ก์‹œ ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํŠธ๋žœ์žญ์…˜์„ ๊ด€๋ฆฌํ•˜๋Š” ๊ณผ์ •์„ ๋ณด์ž.

์ธํ„ฐํŽ˜์ด์Šค ์ •์˜

1
2
3
public interface MyService {
    void performTransaction();
}

MyService๋Š” ํŠธ๋žœ์žญ์…˜์„ ์ˆ˜ํ–‰ํ•  ๋ฉ”์„œ๋“œ๋ฅผ ์ •์˜ํ•œ ์ธํ„ฐํŽ˜์ด์Šค์ž…๋‹ˆ๋‹ค. ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ†ตํ•ด ์„œ๋น„์Šค ๊ตฌํ˜„์ฒด์˜ ๋ฉ”์„œ๋“œ์— ์ ‘๊ทผํ•ฉ๋‹ˆ๋‹ค.

์„œ๋น„์Šค ๊ตฌํ˜„

1
2
3
4
5
6
7
@Service
public class MyServiceImpl implements MyService {
    @Transactional
    public void performTransaction() {
        // ํŠธ๋žœ์žญ์…˜ ๋‚ด์—์„œ ์ˆ˜ํ–‰ํ•  ์ž‘์—…
     }
}

@Transactional ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ performTransaction() ๋ฉ”์„œ๋“œ๋ฅผ ํŠธ๋žœ์žญ์…˜ ์ฒ˜๋ฆฌํ•˜๋„๋ก ํ•œ๋‹ค.
์ด ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋  ๋•Œ ์Šคํ”„๋ง์ด ์ž๋™์œผ๋กœ ํŠธ๋žœ์žญ์…˜์„ ์‹œ์ž‘ํ•˜๊ณ , ๋ฉ”์„œ๋“œ๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ์™„๋ฃŒ๋˜๋ฉด ํŠธ๋žœ์žญ์…˜์„ ์ปค๋ฐ‹ํ•˜๋ฉฐ, ์˜ˆ์™ธ ๋ฐœ์ƒ ์‹œ ๋กค๋ฐฑํ•œ๋‹ค.

ํ”„๋ก์‹œ ๊ฐ์ฒด ์ƒ์„ฑ ๋ฐ ์‚ฌ์šฉ

1
2
3
   // ํ”„๋ก์‹œ ๊ฐ์ฒด ์ƒ์„ฑ ๋ฐ ์‚ฌ์šฉ
MyService myService = (MyService) context.getBean("myService");
myService.performTransaction();

context.getBean(โ€œmyServiceโ€)๋Š” MyService ํƒ€์ž…์˜ ํ”„๋ก์‹œ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์ด ํ”„๋ก์‹œ๋Š” ์Šคํ”„๋ง์ด ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•œ ๋™์  ํ”„๋ก์‹œ๋กœ, ์‹ค์ œ MyServiceImpl์˜ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๊ธฐ ์ „์— ํŠธ๋žœ์žญ์…˜ ๊ด€๋ จ ๋กœ์ง์„ ์ฒ˜๋ฆฌํ•˜๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. myService.performTransaction()์„ ํ˜ธ์ถœํ•˜๋ฉด, ํ”„๋ก์‹œ ๊ฐ์ฒด๊ฐ€ ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ€๋กœ์ฑ„๊ณ , ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ ์ „์— ํŠธ๋žœ์žญ์…˜์„ ์‹œ์ž‘ํ•˜๊ณ , ๋ฉ”์„œ๋“œ ์ข…๋ฃŒ ํ›„ ์ปค๋ฐ‹ ๋˜๋Š” ๋กค๋ฐฑ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค

์Šคํ”„๋ง์€ @Transactional์ด ๋ถ™์€ ๋ฉ”์„œ๋“œ๋ฅผ ์‹คํ–‰ํ•  ๋•Œ, JDK ๋™์  ํ”„๋ก์‹œ๋‚˜ CGLIB์„ ์‚ฌ์šฉํ•ด ํ”„๋ก์‹œ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•œ๋‹ค. ์ด ํ”„๋ก์‹œ๋Š” ์›๋ž˜ ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ ์ „์— ํŠธ๋žœ์žญ์…˜์„ ์‹œ์ž‘ํ•˜๊ณ , ๋ฉ”์„œ๋“œ ์™„๋ฃŒ ์‹œ ํŠธ๋žœ์žญ์…˜์„ ์ปค๋ฐ‹ํ•˜๊ฑฐ๋‚˜, ์˜ˆ์™ธ ๋ฐœ์ƒ ์‹œ ๋กค๋ฐฑํ•œ๋‹ค.

์ด ์ฝ”๋“œ์—์„œ๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์‚ฌ์šฉํ–ˆ์œผ๋ฏ€๋กœ JDK ๋™์  ํ”„๋ก์‹œ๊ฐ€ ์‚ฌ์šฉ๋œ๋‹ค.
๋งŒ์•ฝ ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ์—†๋‹ค๋ฉด CGLIB ํ”„๋ก์‹œ๊ฐ€ ์‚ฌ์šฉ๋œ๋‹ค.


ํ”„๋ก์‹œ ์ƒ์„ฑ ๋ฐฉ์‹

  • ์ธํ„ฐํŽ˜์ด์Šค ๊ธฐ๋ฐ˜ ํ”„๋ก์‹œ: ์Šคํ”„๋ง์€ ๊ธฐ๋ณธ์ ์œผ๋กœ JDK ๋™์  ํ”„๋ก์‹œ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ํ”„๋ก์‹œ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

  • ํด๋ž˜์Šค ๊ธฐ๋ฐ˜ ํ”„๋ก์‹œ (CGLIB):
    ๋งŒ์•ฝ ๋นˆ์ด ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜์ง€ ์•Š์•˜๋‹ค๋ฉด, ์Šคํ”„๋ง์€ CGLIB๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํด๋ž˜์Šค ๊ธฐ๋ฐ˜ ํ”„๋ก์‹œ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.




๊ทธ๋Ÿฌ๋ฉด @Transactional์€ ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ• ๊นŒ?

๋ฉ”์„œ๋“œ์˜ ํ˜ธ์ถœ์ด ์‹œ์ž‘๋จ๋ฉด ํŠธ๋žœ์žญ์…˜์ด ์‹œ์ž‘๋˜๊ณ , ๋ฉ”์„œ๋“œ๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ์ข…๋ฃŒ๋˜๋ฉด ํŠธ๋žœ์žญ์…˜์ด ์ปค๋ฐ‹๋˜๋ฉฐ, ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ํŠธ๋žœ์žญ์…˜์ด ๋กค๋ฐฑ๋œ๋‹ค.

1. ํ”„๋ก์‹œ ๊ฐ์ฒด ์ƒ์„ฑ

  • ์Šคํ”„๋ง์€ @Transactional์ด ์ ์šฉ๋œ ํด๋ž˜์Šค ๋˜๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ์‹ธ๋Š” ํ”„๋ก์‹œ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.
  • ์ด ํ”„๋ก์‹œ๋Š” ์‹ค์ œ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฐ์ฒด๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ, ํŠธ๋žœ์žญ์…˜ ๊ด€๋ จ ๋กœ์ง์„ ์ฒ˜๋ฆฌํ•œ๋‹ค.

2. ํŠธ๋žœ์žญ์…˜ ์‹œ์ž‘

  • ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ์ด ์‹œ์ž‘๋˜๋ฉด, ํ”„๋ก์‹œ๋Š” ๋จผ์ € ํŠธ๋žœ์žญ์…˜ ๋งค๋‹ˆ์ €๋ฅผ ํ†ตํ•ด ์ƒˆ๋กœ์šด ํŠธ๋žœ์žญ์…˜์„ ์‹œ์ž‘ํ•œ๋‹ค.
  • ์ด ๊ณผ์ •์—์„œ ํŠธ๋žœ์žฏ์…˜ ๊ฒฝ๊ณ„๊ฐ€ ์„ค์ •๋˜๋ฉฐ, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋Œ€ํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ๊ธฐ๋ก๋œ๋‹ค.

3. ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ์‹คํ–‰

  • ์‹ค์ œ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์ด ๋‹ด๊ธด ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค. ์ด ๋ฉ”์„œ๋“œ๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋Œ€ํ•œ ์ฝ๊ธฐ, ์“ฐ๊ธฐ ์ž‘์—…์„ ํ•œ๋‹ค.

4. ํŠธ๋žœ์žญ์…˜ ์ปค๋ฐ‹ ๋˜๋Š” ๋กค๋ฐฑ

  • ๋ฉ”์„œ๋“œ๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ์ข…๋ฃŒ๋˜๋ฉด, ํ”„๋ก์‹œ๋Š” ํŠธ๋žœ์žญ์…˜์„ ์ปค๋ฐ‹ํ•œ๋‹ค.
  • ๋ฉ”์„œ๋“œ ์‹คํ–‰ ์ค‘ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด, ํ”„๋ก์‹œ๋Š” ํŠธ๋žœ์žญ์…˜์„ ๋กค๋ฐฑํ•œ๋‹ค.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Service
public class OrderService {
    
    @Autowired
    private OrderRepository orderRepository;

    @Transactional
    public void placeOrder(Order order) {
        // ํŠธ๋žœ์žญ์…˜ ์‹œ์ž‘
        orderRepository.save(order);
        // ์ถ”๊ฐ€ ๋กœ์ง
        // ํŠธ๋žœ์žญ์…˜ ์ปค๋ฐ‹
    }
}

์œ„์˜ OrderService ํด๋ž˜์Šค์—์„œ placeOrder ๋ฉ”์„œ๋“œ๋Š” @Transactional ์• ๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ ํŠธ๋žœ์žญ์…˜ ๊ฒฝ๊ณ„๋ฅผ ์ •์˜ํ•˜๊ณ  ์žˆ๋‹ค.
์Šคํ”„๋ง์€ ์ด ํด๋ž˜์Šค์˜ ํ”„๋ก์‹œ๋ฅผ ์ƒ์„ฑํ•˜์—ฌ placeOrder ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ์„ ๊ฐ€๋กœ์ฑ„๊ณ  ํŠธ๋žœ์žญ์…˜์„ ๊ด€๋ฆฌํ•œ๋‹ค.


ํ”„๋ก์‹œ๊ฐ€ ํŠธ๋žœ์žญ์…˜ ๊ด€๋ฆฌ๋ฅผ ๋Œ€์‹ ํ•˜๋Š” ์ด์œ 

  1. ์ผ๊ด€์„ฑ ์œ ์ง€:
    • ํŠธ๋žœ์žญ์…˜ ๊ด€๋ฆฌ ๋กœ์ง์„ ์ž๋™์œผ๋กœ ์ฒ˜๋ฆฌํ•ด ์คŒ์œผ๋กœ์จ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ์ผ๊ด€์„ฑ๊ณผ ๋ฌด๊ฒฐ์„ฑ์„ ์‰ฝ๊ฒŒ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค.
  2. ์ฝ”๋“œ ๊ฐ„๊ฒฐํ™”:
    • ํŠธ๋žœ์žญ์…˜ ๊ด€๋ฆฌ๋ฅผ ์ฝ”๋“œ์—์„œ ์ง์ ‘ ๊ตฌํ˜„ํ•˜์ง€ ์•Š์•„๋„ ๋˜๋ฏ€๋กœ ์ฝ”๋“œ๊ฐ€ ๊ฐ„๊ฒฐํ•ด์ง„๋‹ค.
  3. ์ค‘๋ณต ๋ฐฉ์ง€:
    • ๋™์ผํ•œ ํŠธ๋žœ์žญ์…˜ ๊ด€๋ฆฌ ๋กœ์ง์„ ์—ฌ๋Ÿฌ ๊ณณ์—์„œ ๋ฐ˜๋ณตํ•ด์„œ ์ž‘์„ฑํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค.
  4. AOP ์ง€์›:
    • ํ”„๋ก์‹œ๋Š” ์Šคํ”„๋ง AOP๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํŠธ๋žœ์žญ์…˜ ๊ด€๋ฆฌ์™€ ๊ฐ™์€ ํšก๋‹จ ๊ด€์‹ฌ์‚ฌ๋ฅผ ์‰ฝ๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค€๋‹ค.

ํ”„๋ก์‹œ๋Š” ํŠธ๋žœ์žญ์…˜ ์‹œ์ž‘, ์ปค๋ฐ‹, ๋กค๋ฐฑ๊ณผ ๊ฐ™์€ ์ž‘์—…์„ ๋Œ€์‹  ์ฒ˜๋ฆฌํ•˜์—ฌ ๊ฐœ๋ฐœ์ž๊ฐ€ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์— ์ง‘์ค‘ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๊ณ , ์ด ๊ณผ์ •์—์„œ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ์˜ค๋ฅ˜ ๊ฐ€๋Šฅ์„ฑ์„ ์ค„์—ฌ์ค€๋‹ค.


ํŠธ๋žœ์žญ์…˜ ๊ด€๋ฆฌ๋ฅผ Proxy ์—†์ด ์ง์ ‘ ๊ตฌํ˜„

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@Service
public class OrderService {

    @Autowired
    private OrderRepository orderRepository;
    
    @Autowired
    private PlatformTransactionManager transactionManager;

    public void placeOrder(Order order) {
        TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
        try {
            // ํŠธ๋žœ์žญ์…˜ ์‹œ์ž‘
            orderRepository.save(order);
            // ์ถ”๊ฐ€ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ์ˆ˜ํ–‰
            
            // ํŠธ๋žœ์žญ์…˜ ์ปค๋ฐ‹
            transactionManager.commit(status);
        } catch (Exception ex) {
            // ์˜ˆ์™ธ ๋ฐœ์ƒ ์‹œ ํŠธ๋žœ์žญ์…˜ ๋กค๋ฐฑ
            transactionManager.rollback(status);
            throw ex;  // ์˜ˆ์™ธ ์žฌ๋ฐœ์ƒ
        }
    }
}


ํ”„๋ก์‹œ ์—†์ด ํŠธ๋žœ์žญ์…˜ ๊ด€๋ฆฌ์˜ ๋ฌธ์ œ์ 

  1. ๋ณต์žก์„ฑ ์ฆ๊ฐ€:
    • ํŠธ๋žœ์žญ์…˜์„ ์‹œ์ž‘ํ•˜๊ณ , ์ปค๋ฐ‹ํ•˜๊ฑฐ๋‚˜ ๋กค๋ฐฑํ•˜๋Š” ์ฝ”๋“œ๊ฐ€ ๋ชจ๋“  ํŠธ๋žœ์žญ์…˜ ๋ฉ”์„œ๋“œ์— ๋ฐ˜๋ณต์ ์œผ๋กœ ์ž‘์„ฑ๋˜์–ด์•ผ ํ•œ๋‹ค.
  2. ์˜ค๋ฅ˜ ๊ฐ€๋Šฅ์„ฑ:
    • ํŠธ๋žœ์žญ์…˜ ์‹œ์ž‘, ์ปค๋ฐ‹, ๋กค๋ฐฑ ๋กœ์ง์„ ์ˆ˜๋™์œผ๋กœ ๊ด€๋ฆฌํ•˜๋‹ค ๋ณด๋ฉด ์‹ค์ˆ˜๋กœ ๋น ๋œจ๋ฆฌ๊ฑฐ๋‚˜ ์ž˜๋ชป ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.
  3. ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง๊ณผ ํŠธ๋žœ์žญ์…˜ ๋กœ์ง์˜ ํ˜ผํ•ฉ:
    • ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง๊ณผ ํŠธ๋žœ์žญ์…˜ ๊ด€๋ฆฌ ๋กœ์ง์ด ๊ฐ™์€ ๋ฉ”์„œ๋“œ์— ์„ž์—ฌ ์žˆ์–ด ๊ฐ€๋…์„ฑ์ด ๋–จ์–ด์ง€๊ณ  ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์–ด๋ ต๋‹ค.
  4. ์žฌ์‚ฌ์šฉ์„ฑ ๋ถ€์กฑ:
    • ํŠธ๋žœ์žญ์…˜ ๊ด€๋ฆฌ ๋กœ์ง์ด ํŠน์ • ๋ฉ”์„œ๋“œ์— ๊ณ ์ •๋˜๊ธฐ ๋•Œ๋ฌธ์— ์žฌ์‚ฌ์šฉ์ด ์–ด๋ ต๋‹ค.




ํ”„๋ก์‹œ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ์˜ ์žฅ์ 

  1. ์ฝ”๋“œ ๊ฐ„๊ฒฐ์„ฑ: ํŠธ๋žœ์žญ์…˜ ๊ด€๋ฆฌ ๋กœ์ง์„ ๊ฐ ๋ฉ”์„œ๋“œ์— ์ž‘์„ฑํ•  ํ•„์š” ์—†์ด @Transactional ์• ๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ ํŠธ๋žœ์žญ์…˜ ๊ฒฝ๊ณ„๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.
  2. ์˜ค๋ฅ˜ ๊ฐ์†Œ: ์Šคํ”„๋ง์ด ํŠธ๋žœ์žญ์…˜ ๊ด€๋ฆฌ๋ฅผ ๋Œ€์‹  ์ฒ˜๋ฆฌํ•˜๋ฏ€๋กœ, ๊ฐœ๋ฐœ์ž๊ฐ€ ์‹ค์ˆ˜๋กœ ํŠธ๋žœ์žญ์…˜ ๊ด€๋ฆฌ ๋กœ์ง์„ ์ž˜๋ชป ๊ตฌํ˜„ํ•  ๊ฐ€๋Šฅ์„ฑ์ด ์ค„์–ด๋“ ๋‹ค.
  3. ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ์ง‘์ค‘: ํŠธ๋žœ์žญ์…˜ ๊ด€๋ฆฌ ๋กœ์ง์ด ๋ถ„๋ฆฌ๋˜์–ด ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์— ์ง‘์ค‘ํ•  ์ˆ˜ ์žˆ๋‹ค.
  4. ์žฌ์‚ฌ์šฉ์„ฑ ํ–ฅ์ƒ: ํŠธ๋žœ์žญ์…˜ ๊ด€๋ฆฌ ๋กœ์ง์„ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ณ , ์ฝ”๋“œ ์ค‘๋ณต์ด ์ค„์–ด๋“ ๋‹ค.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
    @Service
    public class OrderService {
    
     @Autowired
     private OrderRepository orderRepository;
    
     @Transactional
     public void placeOrder(Order order) {
         orderRepository.save(order);
         // ์ถ”๊ฐ€ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ์ˆ˜ํ–‰
     }
    } 
    

@Transactional ์• ๋…ธํ…Œ์ด์…˜์„ ์ด์šฉํ•˜๋ฉด ์Šคํ”„๋ง ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ํ”„๋ก์‹œ๋ฅผ ํ†ตํ•ด ํŠธ๋žœ์žญ์…˜ ๊ด€๋ฆฌ๋ฅผ ๋Œ€์‹ ํ•ด์ค€๋‹ค.




@Transactional๊ณผ ํ”„๋ก์‹œ์˜ ๊ด€๊ณ„

  1. AOP์™€ ํ”„๋ก์‹œ ํŒจํ„ด:
    • ์Šคํ”„๋ง์€ AOP๋ฅผ ์ด์šฉํ•˜์—ฌ @Transactional ์• ๋…ธํ…Œ์ด์…˜์„ ์ ์šฉํ•  ๋•Œ ํ”„๋ก์‹œ ํŒจํ„ด์„ ์‚ฌ์šฉํ•œ๋‹ค.
    • AOP๋Š” ์ฝ”๋“œ์˜ ํ•ต์‹ฌ ๊ธฐ๋Šฅ๊ณผ ๊ณตํ†ต๋œ ๊ธฐ๋Šฅ(๋ถ€๊ฐ€ ๊ธฐ๋Šฅ)์„ ๋ชจ๋“ˆํ™”ํ•˜์—ฌ ๊ด€๋ฆฌํ•˜๋Š” ๊ธฐ์ˆ ์ด๋‹ค.
  2. ํ”„๋ก์‹œ์˜ ์—ญํ• :
    • @Transactional ๋ถ™์€ ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋  ๋•Œ, ์Šคํ”„๋ง ํ”„๋ ˆ์ž„์›Œํฌ๋Š” ๊ทธ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๊ธฐ ์ „ํ›„์— ์ถ”๊ฐ€์ ์ธ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ํ”„๋ก์‹œ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.
    • ์ด ํ”„๋ก์‹œ ๊ฐ์ฒด๋Š” ์›๋ณธ ๊ฐ์ฒด(์„œ๋น„์Šค ํด๋ž˜์Šค)๋ฅผ ๊ฐ์‹ธ๋ฉฐ, ํŠธ๋žœ์žญ์…˜ ๊ด€๋ฆฌ์™€ ๊ฐ™์€ ๊ณตํ†ต๋œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•œ๋‹ค.
  3. ํŠธ๋žœ์žญ์…˜ ๊ด€๋ฆฌ:
    • @Transactional ๋ถ™์€ ๋ฉ”์„œ๋“œ๋Š” ํŠธ๋žœ์žญ์…˜ ํ”„๋ก์‹œ์— ์˜ํ•ด ๊ฐ์‹ธ์ ธ ์‹คํ–‰๋œ๋‹ค
    • ํ”„๋ก์‹œ๋Š” ํŠธ๋žœ์žญ์…˜์„ ์‹œ์ž‘ํ•œ ํ›„ ๋ฉ”์„œ๋“œ๋ฅผ ์‹คํ–‰ํ•˜๊ณ , ๊ทธ ๊ฒฐ๊ณผ์— ๋”ฐ๋ผ ์ปค๋ฐ‹ ๋˜๋Š” ๋กค๋ฐฑํ•œ๋‹ค.
    • ์ด๋กœ ์ธํ•ด ๋ฐ์ดํ„ฐ์˜ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค.
  4. ๊ฐ„ํŽธํ•œ ์„ค์ •:
    • ๊ฐœ๋ฐœ์ž๋Š” @Transactional ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ„ํŽธํ•˜๊ฒŒ ํŠธ๋žœ์žญ์…˜ ๊ฒฝ๊ณ„๋ฅผ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค.
    • ์ด๋Š” ์ฝ”๋“œ๋ฅผ ๊ฐ„๊ฒฐํ•˜๊ฒŒ ์œ ์ง€ํ•˜๊ณ , ์ผ๊ด€๋œ ํŠธ๋žœ์žญ์…˜ ์ฒ˜๋ฆฌ๋ฅผ ๋ณด์žฅํ•œ๋‹ค.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@Service
public class OrderService {

    @Autowired
    private OrderRepository orderRepository;

    @Transactional
    public void placeOrder(Order order) {
        // ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ์ˆ˜ํ–‰
        orderRepository.save(order);
        // ์ถ”๊ฐ€์ ์ธ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ž‘์—… ๋“ฑ
    }

    // ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜ ๋ฉ”์„œ๋“œ
    @Transactional
    public void cancelOrder(Order order) {
        order.setStatus(OrderStatus.CANCELED);
        orderRepository.save(order);
        // ์ถ”๊ฐ€์ ์ธ ๋กœ์ง ์ˆ˜ํ–‰
    }
}


์ด ์˜ˆ์‹œ์—์„œ @Transactional ์• ๋…ธํ…Œ์ด์…˜์ด ๋ถ™์€ placeOrder()์™€ cancelOrder() ๋ฉ”์„œ๋“œ๋Š” ์Šคํ”„๋ง ํ”„๋ก์‹œ๊ฐ€ ๊ด€๋ฆฌํ•˜๋Š” ํŠธ๋žœ์žญ์…˜ ๋ฒ”์œ„์—์„œ ์‹คํ–‰๋œ๋‹ค.
๋ฉ”์„œ๋“œ ๋‚ด์˜ ๋ชจ๋“  ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ์‚ฐ์€ ํ•˜๋‚˜์˜ ํŠธ๋žœ์žญ์…˜์œผ๋กœ ๋ฌถ์—ฌ ์‹คํ–‰๋œ๋‹ค.

๋”ฐ๋ผ์„œ @Transactional์„ ์ด์šฉํ•˜๋ฉด ๊ฐœ๋ฐœ์ž๋Š” ํŠธ๋žœ์žญ์…˜ ๊ด€๋ฆฌ์— ๋Œ€ํ•œ ๋ณต์žกํ•œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜์ง€ ์•Š์•„๋„ ๋˜๋ฉฐ, ์Šคํ”„๋ง ํ”„๋ก์‹œ๊ฐ€ ์ด๋ฅผ ๋Œ€์‹  ์ฒ˜๋ฆฌํ•˜์—ฌ ์ฝ”๋“œ์˜ ๊ฐ„๊ฒฐ์„ฑ๊ณผ ์œ ์ง€๋ณด์ˆ˜์„ฑ์„ ๋†’์—ฌ์ค€๋‹ค.

This post is licensed under CC BY 4.0 by the author.