# ํŠธ๋žœ์žญ์…˜ AOP @Transactional ์‚ฌ์šฉ ์‹œ ์ฃผ์˜์‚ฌํ•ญ
Study Repository

ํŠธ๋žœ์žญ์…˜ AOP @Transactional ์‚ฌ์šฉ ์‹œ ์ฃผ์˜์‚ฌํ•ญ

by rlaehddnd0422

ํŠธ๋žœ์žญ์…˜์ด๋ž€?

ํŠธ๋žœ์žญ์…˜์ด๋ž€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ์ƒํƒœ๋ฅผ ๋ณ€ํ™”์‹œํ‚ค๋Š” ํ•˜๋‚˜์˜ ๋…ผ๋ฆฌ์  ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•œ ์ž‘์—…์ด ๋‹จ์œ„, ์ผ๋ จ์˜ ์—ฐ์‚ฐ๋“ค์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

 

ํŠธ๋žœ์žญ์…˜(Transaction)์ด๋ž€?

ํŠธ๋žœ์žญ์…˜์ด๋ž€? ํŠธ๋žœ์žญ์…˜์ด๋ž€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ์ƒํƒœ๋ฅผ ๋ณ€ํ™”์‹œํ‚ค๋Š” ํ•˜๋‚˜์˜ ๋…ผ๋ฆฌ์  ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•œ ์ž‘์—…์˜ ๋‹จ์œ„ ๋˜๋Š” ํ•œ๊บผ๋ฒˆ์— ๋ชจ๋‘ ์ˆ˜ํ–‰๋˜์–ด์•ผ ํ•  ์ผ๋ จ์˜ ์—ฐ์‚ฐ๋“ค์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ํŠธ๋žœ์žญ์…˜์˜

rlaehddnd0422.tistory.com

 

์Šคํ”„๋ง์—์„œ๋Š” JDBC, JPA ๋“ฑ ์—ฌ๋Ÿฌ ๋ฐ์ดํ„ฐ ์ ‘๊ทผ ๊ธฐ์ˆ ์„ ํŽธ๋ฆฌํ•˜๊ฒŒ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ํŠธ๋žœ์žญ์…˜ ์ถ”์ƒํ™”(PlatformTransactionManager)์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๋˜ ์—ฌ๋Ÿฌ ๋ฐ์ดํ„ฐ ์ ‘๊ทผ ๊ธฐ์ˆ ๋“ค(JDBC, Mybatis, JPA ๋“ฑ) ์— ๋Œ€ํ•œ ํŠธ๋žœ์žญ์…˜ ๋งค๋‹ˆ์ €๋ฅผ PlatformTransactionManager์˜ ๊ตฌํ˜„์ฒด๋กœ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. 

 

PlatformTransactionManager.interface 

public interface PlatformTransactionManager extends TransactionManager {


   TransactionStatus getTransaction(@Nullable TransactionDefinition definition)
         throws TransactionException;

   void commit(TransactionStatus status) throws TransactionException;

   void rollback(TransactionStatus status) throws TransactionException;

}

 

 

ํŠธ๋žœ์žญ์…˜ ์ธํ„ฐํŽ˜์ด์Šค, ํŠธ๋žœ์žญ์…˜ ํ…œํ”Œ๋ฆฟ์„ ์ด์šฉํ•œ Service ๊ณ„์ธต์˜ Transaction ๋ฌธ์ œ ํ•ด๊ฒฐ

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ตฌ์กฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ตฌ์กฐ ์ค‘ ๊ฐ€์žฅ ๋‹จ์ˆœํ•˜๋ฉด์„œ ๋งŽ์ด ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์—ญํ• ์— ๋”ฐ๋ผ 3๊ฐ€์ง€ ๊ณ„์ธต์œผ๋กœ ๋‚˜๋ˆ„๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. ์ปจํŠธ๋กค๋Ÿฌ ๊ณ„์ธต ์›น ์š”์ฒญ(request), ์‘๋‹ต(response)๋ฅผ ๊ด€๋ฆฌํ•˜๊ณ  ์‚ฌ์šฉ

rlaehddnd0422.tistory.com

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

 

ํŠธ๋žœ์žญ์…˜ ๋งค๋‹ˆ์ €๋Š” DataSource๋ฅผ ์ฃผ์ž…๋ฐ›์•„ ๋“ฑ๋ก๋˜๋Š”๋ฐ ๊ทธ๋ ‡๋‹ค๋ฉด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์„œ๋ฒ„์— ๋Œ€ํ•œ ์ •๋ณด์ธ DataSource๋Š” ์–ด๋–ป๊ฒŒ ์„ค์ •ํ• ๊นŒ?

๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค.
1. application.properties์— ์„ค์ •์ •๋ณด๋ฅผ ์ž‘์„ฑํ•จ์œผ๋กœ์จ ์Šคํ”„๋ง๋ถ€ํŠธ๊ฐ€ ์„ค์ •์ •๋ณด๋ฅผ ๋ณด๊ณ  ์ž๋™์œผ๋กœ ๋นˆ์œผ๋กœ ๋“ฑ๋กํ•˜๋„๋ก ์œ ๋„ โœ“
2. ์ง์ ‘ ์ˆ˜๋™์œผ๋กœ ๋นˆ ๋“ฑ๋ก
 
์ฃผ๋กœ DataSource๋Š” 1๋ฒˆ ๋ฐฉ๋ฒ•์„ ํ†ตํ•ด ์ƒ์„ฑ ๋ฐ ์ฃผ์ž…ํ•ฉ๋‹ˆ๋‹ค.

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


ํŠธ๋žœ์žญ์…˜ ๋งค๋‹ˆ์ € ์‚ฌ์šฉ ๋ฐฉ๋ฒ•

1. ํŠธ๋žœ์žญ์…˜ ๋งค๋‹ˆ์ € ์ง์ ‘ ์‚ฌ์šฉ

ํŠธ๋žœ์žญ์…˜ ๋งค๋‹ˆ์ € ์„ ์–ธ

@Service
public class MyService {
    @Autowired PlatformTransactionManager transactionManager;
    TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
  • ์Šคํ”„๋ง ๋ถ€ํŠธ๊ฐ€ ์ž๋™์œผ๋กœ ๋“ฑ๋กํ•œ ํŠธ๋žœ์žญ์…˜ ๋งค๋‹ˆ์ €๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค by @Autowired 
  • status๋Š” commit, rollback ์—์„œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

ํŠธ๋žœ์žญ์…˜ ์‹œ์ž‘ - ์ปค๋ฐ‹/๋กค๋ฐฑ 

TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());

public void logic()
{
    try {
        //๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง
        bizLogic(fromId, toId, money);
        transactionManager.commit(status); //์„ฑ๊ณต์‹œ ์ปค๋ฐ‹
    } catch (Exception e) { 
        transactionManager.rollback(status); //์‹คํŒจ์‹œ ๋กค๋ฐฑ
        throw new IllegalStateException(e);
    }
}

2. ๊ฐ„์ ‘์ ์œผ๋กœ ์–ด๋…ธํ…Œ์ด์…˜์„ ํ†ตํ•ด ์‚ฌ์šฉ

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

 

@Transaction 

 

Spring ํŠธ๋žœ์žญ์…˜ AOP - @Transactional ์‚ฌ์šฉ

์ด ์ „ ํฌ์ŠคํŒ…์—์„œ ํŠธ๋žœ์žญ์…˜์„ ํŽธ๋ฆฌํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ํŠธ๋žœ์žญ์…˜ ์ถ”์ƒํ™”์™€ ํŠธ๋žœ์žญ์…˜ ํ…œํ”Œ๋ฆฟ์„ ๋„์ž…ํ•ด๋ณด์•˜์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์—ฌ์ „ํžˆ ์„œ๋น„์Šค ๊ณ„์ธต์— ์ˆœ์ˆ˜ํ•œ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง๋งŒ ๋‚จ๊ธฐ๋Š” ๋ชฉํ‘œ์—๋Š” ๋„๋‹ฌํ•˜

rlaehddnd0422.tistory.com

 

@Service
public class MyService {
	
    @Transactional
    public void logic()
    { 
    	bizlogic();
        ...
    }
}

@Transactional ๋„์ž… ์‹œ ๋™์ž‘๋ฐฉ์‹   

๋ฉ”์†Œ๋“œ๋‚˜ ํด๋ž˜์Šค ๋ ˆ๋ฒจ์— @Transactional์„ ๊ฑธ์–ด์ฃผ๋ฉด 

 

1. AOP ํ”„๋ก์‹œ์—์„œ์Šคํ”„๋ง ๋ถ€ํŠธ๋ฅผ ํ†ตํ•ด ์ž๋™์œผ๋กœ ๋นˆ์œผ๋กœ ๋“ฑ๋ก๋œ ํŠธ๋žœ์žญ์…˜ ๋งค๋‹ˆ์ €๋ฅผ ์‚ฌ์šฉํ•ด ๋“ฑ๋ก๋œ DataSource๋ฅผ ํ†ตํ•ด ์ปค๋„ฅ์…˜์„ ์ƒ์„ฑํ•ด์„œ ํŠธ๋žœ์žญ์…˜ ๋™๊ธฐํ™” ๋งค๋‹ˆ์ €์— ๋ณด๊ด€ํ•˜๊ณ  ํŠธ๋žœ์žญ์…˜์„ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.

 

2. ํŠธ๋žœ์žญ์…˜ ์ฒ˜๋ฆฌ๋กœ์ง์—์„œ ์‹ค์ œ ๋น„์ฆˆ๋‹ˆ์Šค๋กœ์ง์„ ํ˜ธ์ถœํ•˜์—ฌ ํŠธ๋žœ์žญ์…˜์„ ์‹คํ–‰ํ•˜๋Š”๋ฐ ์ด ๋•Œ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ์—์„œ๋Š” ๋™๊ธฐํ™” ๋งค๋‹ˆ์ €์— ๋“ฑ๋ก๋œ ์ปค๋„ฅ์…˜์„ ์–ป์–ด ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

 

3. AOP ํ”„๋ก์‹œ์—์„œ ํŠธ๋žœ์žญ์…˜์— ์„ฑ๊ณตํ•˜๋ฉด commit, ์‹คํŒจํ•˜๋ฉด rollback ํ•ฉ๋‹ˆ๋‹ค.

 

์Šคํ”„๋ง์˜ ํŠธ๋žœ์žญ์…˜ AOP๋Š” @Transactional ์–ด๋…ธํ…Œ์ด์…˜์„ ์ธ์‹ํ•ด์„œ ํŠธ๋žœ์žญ์…˜์„ ์ฒ˜๋ฆฌํ•˜๋Š” ํ”„๋ก์‹œ๋ฅผ ์ ์šฉํ•ด์ค๋‹ˆ๋‹ค.

 

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

 

์ง€๊ธˆ๋ถ€ํ„ฐ @Transactional์„ ์‚ฌ์šฉํ•  ๋•Œ ์ฃผ์˜ํ•ด์•ผ ํ•  ์ ๋“ค๊ณผ @Transactional์˜ ์˜ต์…˜๋“ค์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.


ํŠธ๋žœ์žญ์…˜ ์ ์šฉ ํ™•์ธํ•˜๊ธฐ

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

 

AopUtils.isAopProxy(๊ฐ์ฒด) ๋ฅผ ์ด์šฉํ•˜๋ฉด ๋Œ€์ƒ ๊ฐ์ฒด๊ฐ€ ํŠธ๋žœ์žญ์…˜ AOP๊ฐ€ ์ ์šฉ๋œ ๊ฐ์ฒด์ธ์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

 

@Transactional ์–ด๋…ธํ…Œ์ด์…˜์„ ํ†ตํ•ด ํŠธ๋žœ์žญ์…˜์ด ์ ์šฉ๋˜๊ณ  ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•œ ๋ฐฉ๋ฒ• 

TransactionSynchronizationManager.isActualTransactionActive() 

static class BasicService
{
	@Transactional
    public void tx() {
        log.info("call tx");
        boolean txActive = TransactionSynchronizationManager.isActualTransactionActive();
        log.info("tx active = {}",txActive);
    }

    public void nonTx()
    {
        log.info("call nontx");
        boolean txActive = TransactionSynchronizationManager.isActualTransactionActive();
        log.info("tx active = {}",txActive);
    }
}
@Test
void txTest()
{
    basicService.tx();
    basicService.nonTx();
}

์‹คํ–‰ ๊ฒฐ๊ณผ

ํŠธ๋žœ์žญ์…˜ ์ ์šฉ ์œ„์น˜

์Šคํ”„๋ง์€ ํ•ญ์ƒ ๋” ๊ตฌ์ฒด์ ์ด๊ณ  ์ž์„ธํ•œ ๊ฒƒ์ด ๋†’์€ ์šฐ์„  ์ˆœ์œ„๋ฅผ ๊ฐ€์ง‘๋‹ˆ๋‹ค. ๊ฐ€๋ น @Transactional์— readOnly ์˜ต์…˜์„ true๋กœ ํด๋ž˜์Šค๋ ˆ๋ฒจ์— ์ ์šฉํ•˜๊ณ , ๋ฉ”์†Œ๋“œ๋ ˆ๋ฒจ์—์„œ @Transactional readOnly ์˜ต์…˜์„ false๋กœ ์ง€์ •ํ•˜๋ฉด ํ•ด๋‹น ๋ฉ”์†Œ๋“œ๋Š” readOnly ์˜ต์…˜์ด false๋กœ ์ง€์ •๋˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ง์ด์ฃ .

 

readOnly ์˜ต์…˜์€ ๋’ค์—์„œ ์ž์„ธํžˆ ์„ค๋ช…ํ•˜๊ฒ ์ง€๋งŒ, ์—ฌ๊ธฐ์„œ ๊ฐ„๋‹จํžˆ ๋งํ•˜์ž๋ฉด ์ฝ๊ธฐ ์ „์šฉ ํŠธ๋žœ์žญ์…˜์„ ์ ์šฉํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

ํ•ด๋‹น ํŠธ๋žœ์žญ์…˜์— ์ฝ๊ธฐ ์ „์šฉ ํŠธ๋žœ์žญ์…˜์ด ์ ์šฉ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๋ฐฉ๋ฒ•์€

TransactionSynchronizationManager.isCurrentTransactionReadOnly() ๋ฉ”์†Œ๋“œ๋ฅผ ํ†ตํ•ด ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

์ถ”๊ฐ€์ ์œผ๋กœ @Transactional์€ ํด๋ž˜์Šค๋‚˜ ๋ฉ”์†Œ๋“œ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์ธํ„ฐํŽ˜์ด์Šค์—๋„ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, ์ธํ„ฐํŽ˜์ด์Šค์— ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ๊ถŒ์žฅ๋˜์ง„ ์•Š์Šต๋‹ˆ๋‹ค. ์ ์šฉํ•˜๊ฒŒ ๋œ๋‹ค๋ฉด ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ๊ฐ€์žฅ ๋œ ๊ตฌ์ฒด์ ์ธ ๋ ˆ๋ฒจ์ด๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ€์žฅ ๋‚ฎ์€ ์šฐ์„ ์ˆœ์œ„๋ฅผ ๊ฐ€์ง‘๋‹ˆ๋‹ค.


ํŠธ๋žœ์žญ์…˜ AOP @Transactional ์‚ฌ์šฉ ์‹œ ์ฃผ์˜์‚ฌํ•ญ 1 - ํ”„๋ก์‹œ ๋‚ด๋ถ€ ํ˜ธ์ถœ

๊ฒฐ๋ก ์ ์œผ๋กœ ๋งํ•˜์ž๋ฉด ๋™์ผ ํด๋ž˜์Šค ๋‚ด๋ถ€์— ์กด์žฌํ•˜๋Š” ๋ฉ”์†Œ๋“œ1๊ณผ ๋ฉ”์†Œ๋“œ2๊ฐ€ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•  ๋•Œ,  @Transactional์ด ์ ์šฉ๋˜์ง€ ์•Š์€ ๋ฉ”์†Œ๋“œ1์—์„œ ๋‚ด๋ถ€ ํ˜ธ์ถœ๋กœ @Transactional์ด ์ ์šฉ๋œ ๋ฉ”์†Œ๋“œ2๋ฅผ ํ˜ธ์ถœ์„ ํ•˜๊ฒŒ ๋˜๋ฉด ๋ฉ”์†Œ๋“œ2์—๋Š” @Transactional์ด ์ ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.  

 

์™œ ๊ทธ๋Ÿฐ๊ฑธ๊นŒ์š”? ๊ตฌ์กฐ๋ฅผ ์‚ดํŽด๋ณด๋ฉด

@Transactional์ด ์ ์šฉ๋œ ๋ฉ”์†Œ๋“œ๋Š”

1. AOP ํ”„๋ก์‹œ ๊ฐ€์งœ ๊ฐ์ฒด์—์„œ @Transactional์ด ๋ถ™์€ ํ•ด๋‹น ๋ฉ”์†Œ๋“œ๋ฅผ ์‹คํ–‰ํ•˜๊ณ 

2. ์‹ค์ œ ๊ฐ์ฒด๋ฅผ ํ˜ธ์ถœ๋˜์–ด ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. 

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

๋”ฐ๋ผ์„œ @Transactional์ด ๋ถ™์–ด์žˆ๋‹ค ํ•˜๋”๋ผ๋„ ์‹ค์ œ ๊ฐ์ฒด์—์„œ๋Š” ์ด๋ฅผ ์ธ์‹ํ•˜์ง€ ๋ชปํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํŠธ๋žœ์žญ์…˜์ด ์ ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

ํ•ด๊ฒฐ๋ฒ•

์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ํด๋ž˜์Šค๋ฅผ ๋ถ„๋ฆฌํ•ด์ฃผ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

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


ํŠธ๋žœ์žญ์…˜ AOP @Transactional ์‚ฌ์šฉ ์‹œ ์ฃผ์˜์‚ฌํ•ญ 2 - public ๋ฉ”์†Œ๋“œ

@Transactional์€ public ๋ฉ”์†Œ๋“œ์—๋งŒ ์ ์šฉ๋˜๋„๋ก ๊ธฐ๋ณธ ์„ค์ •์ด ๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ ์™ธ์˜ ์ ‘๊ทผ ์ œ์–ด์ž์—๋Š” ์ ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

 

@Transactional์„ ์ ์šฉํ•˜๋ฉด ๊ฐ€์งœ ํ”„๋ก์‹œ ๊ฐ์ฒด๊ฐ€ ๋งŒ๋“ค์–ด ์ง€๋Š”๋ฐ, public์ด ์•„๋‹Œ ๋‹ค๋ฅธ ์ ‘๊ทผ์ œ์–ด์ž๋กœ ๋ง‰์•„๋‘”๋‹ค๋ฉด ํ”„๋ก์‹œ ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ํ˜ผ๋ž€์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ์Šคํ”„๋ง์€ ์ผ๋ฐ˜์ ์œผ๋กœ public ๋ฉ”์†Œ๋“œ์—๋งŒ @Transactional ์–ด๋…ธํ…Œ์ด์…˜์„ ์ ์šฉํ•˜๋„๋ก ์„ค์ •๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.


ํŠธ๋žœ์žญ์…˜ AOP @Transactional ์‚ฌ์šฉ ์‹œ ์ฃผ์˜์‚ฌํ•ญ 3 - ์ดˆ๊ธฐํ™” ์‹œ์ 

@PostConstruct์™€ @Transactional์„ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋ฉด ํŠธ๋žœ์žญ์…˜์ด ์ ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

 

ํ•จ๊ป˜ ์ ์šฉํ•˜๊ฒŒ ๋˜๋ฉด @PostConstruct๋กœ ์ดˆ๊ธฐํ™” ์ฝ”๋“œ๊ฐ€ ๋จผ์ € ํ˜ธ์ถœ๋œ ์ดํ›„์— ๊ทธ ๋‹ค์Œ์— ํŠธ๋žœ์žญ์…˜ AOP๊ฐ€ ์ ์šฉ๋˜๊ธฐ ๋•Œ๋ฌธ์— ํŠธ๋žœ์žญ์…˜์ด ์ ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

 

์ดˆ๊ธฐํ™” ์ดํ›„ ์ฝ”๋“œ๊ฐ€ ํ˜ธ์ถœ๋˜๊ธฐ ์ „์— ํŠธ๋žœ์žญ์…˜ AOP๋ฅผ ์ ์šฉ์‹œํ‚ค๊ณ  ์‹ถ๋‹ค๋ฉด @PostConstruct๋Œ€์‹  @EventListener(value = ApplicationReadyEvent.class)๋ฅผ ์ ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. 

 

@EventListener ์–ด๋…ธํ…Œ์ด์…˜์€ ์Šคํ”„๋ง ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ์ œ๊ณตํ•˜๋Š” ์–ด๋…ธํ…Œ์ด์…˜ ์ค‘ ํ•˜๋‚˜๋กœ, ์ด๋ฒคํŠธ๋ฅผ ์ˆ˜์‹ ํ•˜๊ณ  ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฉ”์†Œ๋“œ๋ฅผ ์ •์˜ํ•  ๋•Œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

@EventListener ์–ด๋…ธํ…Œ์ด์…˜์€ ๋ฉ”์†Œ๋“œ์— ์ ์šฉ๋˜๋ฉฐ, ๋ฉ”์†Œ๋“œ๊ฐ€ ์ด๋ฒคํŠธ๋ฅผ ์ˆ˜์‹ ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.
์ด๋ฒคํŠธ๋Š” ์Šคํ”„๋ง ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๋ฐœ์ƒํ•˜๋Š” ๋‹ค์–‘ํ•œ ์ด๋ฒคํŠธ ์ค‘ ํ•˜๋‚˜์ผ ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์˜ˆ๋ฅผ ๋“ค์–ด ApplicationReadyEvent๋Š” ์Šคํ”„๋ง ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์‹œ์ž‘๋˜๊ณ  ์ดˆ๊ธฐํ™”๋˜๊ณ  ์ค€๋น„๋œ ํ›„ ๋ฐœ์ƒํ•˜๋Š” ์ด๋ฒคํŠธ์ž…๋‹ˆ๋‹ค.

<์ •๋ฆฌ>

ํŠธ๋žœ์žญ์…˜ AOP์˜ ๋™์ž‘๋ฐฉ์‹์„ ๋‹ค์‹œ ํ•œ๋ฒˆ ์‚ดํŽด๋ณด์•˜์Šต๋‹ˆ๋‹ค.

 

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

  1. @Transactional ์–ด๋…ธํ…Œ์ด์…˜์ด ์ ์šฉ๋œ ๋ฉ”์†Œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋˜๋ฉด, ์Šคํ”„๋ง์€ ํ”„๋ก์‹œ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  2. ํ”„๋ก์‹œ ๊ฐ์ฒด๋Š” ์›๋ณธ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ•˜๊ณ , ์›๋ณธ ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๊ธฐ ์ „์— ํŠธ๋žœ์žญ์…˜์„ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.
  3. ์›๋ณธ ๋ฉ”์†Œ๋“œ๊ฐ€ ์‹คํ–‰๋˜๋ฉด, ํ”„๋ก์‹œ ๊ฐ์ฒด๋Š” ํ•ด๋‹น ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๊ณ , ๋ฉ”์†Œ๋“œ ์‹คํ–‰ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
  4. ์›๋ณธ ๋ฉ”์†Œ๋“œ์˜ ์‹คํ–‰์ด ์ •์ƒ์ ์œผ๋กœ ์ข…๋ฃŒ๋˜๋ฉด, ํ”„๋ก์‹œ ๊ฐ์ฒด๋Š” ํŠธ๋žœ์žญ์…˜์„ ์ปค๋ฐ‹ํ•ฉ๋‹ˆ๋‹ค. ์ด๋•Œ, ์ปค๋ฐ‹์ด ์‹คํŒจํ•˜๋ฉด ๋กค๋ฐฑํ•ฉ๋‹ˆ๋‹ค.
  5. ์›๋ณธ ๋ฉ”์†Œ๋“œ์˜ ์‹คํ–‰ ์ค‘ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด, ํ”„๋ก์‹œ ๊ฐ์ฒด๋Š” ํŠธ๋žœ์žญ์…˜์„ ๋กค๋ฐฑํ•ฉ๋‹ˆ๋‹ค.

์œ„์™€ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ @Transactional ์–ด๋…ธํ…Œ์ด์…˜์ด ์ ์šฉ๋œ ๋ฉ”์†Œ๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด, ํ•ด๋‹น ๋ฉ”์†Œ๋“œ๊ฐ€ ์‹คํ–‰๋˜๋Š” ๋™์•ˆ์—๋Š” ํ•˜๋‚˜์˜ ํŠธ๋žœ์žญ์…˜์œผ๋กœ ๋ฌถ์—ฌ์„œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ž‘์—… ๋“ฑ์˜ ์ผ๊ด„ ์ฒ˜๋ฆฌ ์ž‘์—…์„ ์•ˆ์ „ํ•˜๊ฒŒ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ ์Šคํ”„๋ง์€ AOP(Aspect Oriented Programming)์„ ์‚ฌ์šฉํ•˜์—ฌ @Transactional ์–ด๋…ธํ…Œ์ด์…˜์ด ์ ์šฉ๋œ ๋ฉ”์†Œ๋“œ๋ฅผ ํ”„๋ก์‹œ ๊ฐ์ฒด๋กœ ๊ฐ์‹ธ๊ณ , ํŠธ๋žœ์žญ์…˜ ์ฒ˜๋ฆฌ๋ฅผ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

 

์ด๋•Œ, AOP๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ”„๋ก์‹œ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์‹œ์ ์—์„œ ๋ฉ”์†Œ๋“œ์˜ ์ ‘๊ทผ ์ œ์–ด์ž์— ๋”ฐ๋ผ ํ”„๋ก์‹œ ๊ฐ์ฒด์˜ ์ƒ์„ฑ ๋ฐฉ์‹์ด ๊ฒฐ์ •๋ฉ๋‹ˆ๋‹ค.

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

 

  • @Transactional์„ ์‚ฌ์šฉํ•  ๋•Œ ์ฃผ์˜ํ•ด์•ผ ํ•  ์ ๋“ค์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด์•˜์Šต๋‹ˆ๋‹ค.
    • @Transactional์€ Proxy๋กœ ๋™์ž‘ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ๊ธฐ์–ตํ•ฉ์‹œ๋‹ค.
    • @Transactional์€ public ๋ฉ”์†Œ๋“œ์—๋งŒ ์ ์šฉ๋ฉ๋‹ˆ๋‹ค.
    • @PostConstruct์™€ @Transactional์„ ๊ฐ™์ด ์ ์šฉํ•˜๊ฒŒ๋˜๋ฉด ํŠธ๋žœ์žญ์…˜์ด AOP๊ฐ€ ์ ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

 


<์ฐธ๊ณ ์ž๋ฃŒ>

 

 

์Šคํ”„๋ง DB 2ํŽธ - ๋ฐ์ดํ„ฐ ์ ‘๊ทผ ํ™œ์šฉ ๊ธฐ์ˆ  - ์ธํ”„๋Ÿฐ | ๊ฐ•์˜

๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ์— ํ•„์š”ํ•œ DB ๋ฐ์ดํ„ฐ ์ ‘๊ทผ ๊ธฐ์ˆ ์„ ํ™œ์šฉํ•˜๊ณ , ์™„์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์Šคํ”„๋ง DB ์ ‘๊ทผ ๊ธฐ์ˆ ์˜ ์›๋ฆฌ์™€ ๊ตฌ์กฐ๋ฅผ ์ดํ•ดํ•˜๊ณ , ๋” ๊นŠ์ด์žˆ๋Š” ๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ์ž๋กœ ์„ฑ์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค., - ๊ฐ•์˜ ์†Œ๊ฐœ | ์ธ

www.inflearn.com

 

 

Proxyํ˜•ํƒœ๋กœ ๋™์ž‘ํ•˜๋Š” JPA @Transactional

๋ณธ ํฌ์ŠคํŒ…์€ ์•„๋ž˜ ํ‚ค์›Œ๋“œ๋ฅผ ๊ฒ€์ƒ‰ํ•˜๋Š” ๋ถ„๋“ค์—๊ฒŒ ์ฐธ๊ณ ๊ฐ€ ๋  ๋งŒํ•œ ๊ธ€์ž…๋‹ˆ๋‹ค. Methods annotated with '@Transactional' must be overridable jpa transactional private jpa transaction same class same class transaction not working call trans

cobbybb.tistory.com

 

๋ธ”๋กœ๊ทธ์˜ ์ •๋ณด

Study Repository

rlaehddnd0422

ํ™œ๋™ํ•˜๊ธฐ