๐Ÿ“• Language/Java

[Error ํšŒ๊ณ ] Lock๋ฐฉ์ง€๋ฅผ ์œ„ํ•œ Transaction ๋ถ„๋ฆฌ

a n u e 2022. 2. 16. 09:20

์šด์˜·๊ด€๋ฆฌํ•˜๋Š” ์‚ฌ์ดํŠธ ์ค‘, ์š”๊ทผ๋ž˜ ์œ ๋… ์†๋„๊ฐ€ ์ €ํ•˜๋œ ์‚ฌ์ดํŠธ๊ฐ€ ์žˆ๋‹ค.

์†๋„๋ณด๋‹ค๋„ ํฐ ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ๋Š”๋ฐ ํŠน์ • ํ…Œ์ด๋ธ”์—์„œ DB Lock์ด ์ง€์†์ ์œผ๋กœ ๊ฑธ๋ฆฐ๋‹ค๋Š” ๊ฒƒ์ด์—ˆ๋‹ค. ์ด๊ฒƒ์€ ์†๋„์˜ ๋ฌธ์ œ๊ฐ€ ์•„๋‹Œ ์‚ฌ์šฉ์˜ ๋ฌธ์ œ์ด๊ธฐ ๋•Œ๋ฌธ์— ์ปค๋‹ค๋ž€ ์ด์Šˆ์˜€๋‹ค. '๋ฐ์ดํ„ฐ ์ˆ˜์ •์ด ์•ˆ๋œ๋‹ค, ์ˆ˜์ • ์‹œ ์ž๊พธ ํ™”๋ฉด์ด ๋ฉˆ์ถฐ๋ฒ„๋ฆฐ๋‹ค.' ๋ผ๋Š” ๊ธด๊ธ‰ ์š”์ฒญ์— ๊ธ‰ํ•œ๋Œ€๋กœ ์šฐ์„  Lock์„ killํ•˜๊ธฐ๋ฅผ ์—ฌ๋Ÿฌ๋ฒˆ. ์•ˆ๋˜๊ฒ ๋‹ค์‹ถ์–ด, ์ข€ ๋” ์ž์„ธํžˆ ๋“ค์—ฌ๋‹ค๋ดค๋‹ค.

 

Database๊ฐ€ Oracle์ธ ์‚ฌ์ดํŠธ์˜€๊ณ , ์ด์— Oacle lock์ด ๊ฑธ๋ ค์žˆ๋Š” ํ…Œ์ด๋ธ”๊ณผ SQL query๋ฅผ ์กฐํšŒํ•ด๋ณด์•˜๋‹ค. ์—ญ์‹œ ํŠน์ • ํ…Œ์ด๋ธ”์—์„œ Lock์ด ๊ฑธ๋ ค์žˆ์—ˆ๋Š”๋ฐ, ๋ˆˆ์— ๋„๋Š” ๊ฒƒ์€ ํ•ด๋‹น ํ…Œ์ด๋ธ”๊ณผ ์—…๋ฌด์ ์œผ๋กœ ์—ฎ์—ฌ์žˆ๋Š” ํŠน์ •ํ•œ ํ…Œ์ด๋ธ”๋“ค์ด ํ•จ๊ป˜ ๊ฑธ๋ ค์žˆ๋‹ค๋Š” ์ ์ด์—ˆ๋‹ค.

'์•„, ์ € ํ…Œ์ด๋ธ”๋“ค์ด ๊ณต๋™์œผ๋กœ ๋ฌด์–ธ๊ฐ€ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋‹ค๊ฐ€ Lock์ด ๊ฑธ๋ ธ๊ตฌ๋‚˜. ์ €๊ฒƒ๋“ค์ด ์—ฎ์ธ ์—…๋ฌด๊ฐ€ ๋ญ๊ฐ€ ์žˆ์ง€?'

๊ทธ๋Ÿฌํ•œ ์ƒ๊ฐ๊ณผ Lock์„ ๋ฐœ์ƒ์‹œํ‚จ SQL query์„ ๋”ฐ๋ผ ์˜ฌ๋ผ๊ฐ€๋‹ค๋ณด๋‹ˆ ์ธํ„ฐํŽ˜์ด์Šค๋ผ๋Š” ๊ฒฐ๋ก ์ด ๋‚˜์™”๋‹ค.

 

ํ•ด๋‹น ์ธํ„ฐํŽ˜์ด์Šค์˜ ๋กœ๊ทธ ๊ธฐ๋ก์„ ๋ณด๋‹ˆ, ๊ณ„์†ํ•˜์—ฌ Error Log๊ฐ€ ๋–จ์–ด์ง€๊ณ  ์žˆ์—ˆ๋‹ค.

ํƒ€ ์‹œ์Šคํ…œ๊ณผ ๋ฐ์ดํ„ฐ ์†ก์ˆ˜์‹ ์„ ํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค ์‹œ, ๋‹ค๋Ÿ‰์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ฃผ๊ณ ๋ฐ›๋Š”๋‹ค. ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ฐœ๋ฐœํ•œ ๊ฐœ๋ฐœ์ž์˜ ์—ญ๋Ÿ‰์— ๋”ฐ๋ผ Log์˜ ์งˆ๋„ ์ฒœ์ฐจ๋งŒ๋ณ„์ด๊ธฐ ๋•Œ๋ฌธ์—, Log๋งŒ์œผ๋กœ Error์˜ ์›์ธ์„ ์ถ”์ธกํ•˜๊ธฐ ์–ด๋ ค์› ๋‹ค. 

 

for(Object obj:resultList) {
    Map dataMap = (Map) obj;
    rowData = COMPANYCODE+"|"
            +dataMap.get("ID")+"|"
            +dataMap.get("DESCRIPTION")+"|"
    try {
        if(testDAO.checkMethod(dataMap > 0) {
            testDAO.updateMethod(dataMap);
        } else {
            testDAO.insertMethod(dataMap);
        }
    } catch (SqlIgnoreException se) {
        se.printStackTrace();
        isSuccess = false;
    }
}

 

์ฝ”๋“œ์˜ ์•„์ฃผ ์ผ๋ถ€๋ถ„์„ ๊ฐ€๊ณตํ•˜์—ฌ ๋–ผ์–ด์˜จ ๊ฒƒ์ด๋‹ค. ํ•ด๋‹น ์ธํ„ฐํŽ˜์ด์Šค๋Š” ๋งค์ผ ์ƒˆ๋ฒฝ๋งˆ๋‹ค 1๋ฒˆ์”ฉ ๋ฐฐ์น˜ ์„œ๋น„์Šค๋กœ ๊ตฌ๋™๋˜๊ณ  ์žˆ์—ˆ๋‹ค. ๊ทธ๊ฐ„ ์„ฑ๊ณตํ•˜์ง€ ๋ชปํ•œ ์‹ญ์—ฌ๋งŒ๊ฐœ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ํ•˜๋ฃจ์ข…์ผ ๋ฐ›์•„์˜ค๊ณ  ์žˆ๋Š”๋ฐ(์‹ค์ œ LogํŒŒ์ผ์„ ๋’ค์ ธ๋ณด๋‹ˆ ์ •๋ง ํ•˜๋ฃจ์ข…์ผ ๋Œ๊ณ  ์žˆ์—ˆ๋‹ค. ๊ณตํฌ์Šค๋Ÿฌ์› ๋‹ค..) , ๋™์ผ ํ…Œ์ด๋ธ”์„ ์‚ฌ์šฉํ•˜๋Š” ๋‹ค๋ฅธ ๊ฒŒ์‹œํŒ์—์„œ ๋ฐ์ดํ„ฐ ์ˆ˜์ •์„ ์‹œ๋„ํ•˜๋‹ˆ Lock์ด ๊ฑธ๋ฆด๋งŒ๋„ ํ–ˆ๋‹ค. ๊ทธ๊ฒƒ๋„ ๋ชจ๋ฅด๊ณ  ๊ทธ๋•Œ๊ทธ๋•Œ Lock๋งŒ killํ•˜๊ณ  ์žˆ์œผ๋‹ˆ, ๋‹ค์Œ๋‚ ์ด ๋˜๋ฉด ๋˜ Lock์ด ๊ฑธ๋ฆฌ๋Š”๊ฒŒ ๋‹น์—ฐํ–ˆ๋‹ค.

์ด ์ ์„ ๊ฐœ์„ ํ•˜๊ธฐ ์œ„ํ•˜์—ฌ, ์ € try~catch์˜ method๋“ค์˜ ํŠธ๋žœ์žญ์…˜ ๋ถ„๋ฆฌํ•ด์ฃผ๋Š” ์ž‘์—…์ด ํ•„์š”ํ–ˆ๋‹ค. ์ € 3๊ฐœ์˜ method๋ฅผ ํ•˜๋‚˜์˜ ์ž‘์—…์œผ๋กœ ๋ถ„๋ฅ˜ํ•˜๊ณ , ํ•˜๋‚˜์˜ method์— ๋‹ด์•„ ๊ทธ method๋ฅผ ํŠธ๋žœ์žญ์…˜์œผ๋กœ ๋ฌถ์—ˆ๋‹ค. 

 

@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class, noRollbackFor = SqlIgnoreException.class)
public void testMethod(Map dataMap) throws SqlIgnoreException {
    if(testDAO.checkMethod(dataMap) > 0) {
        testDAO.updateMethod(dataMap);
    } else {
        testDAO.insertMethod(dataMap);
    }
}

for๋ฌธ์œผ๋กœ ์‹ญ์—ฌ๋งŒ๊ฐœ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์˜ค๋”๋ผ๋„, ๊ฑด ๋‹น Commit์ด ๋˜๋ฏ€๋กœ ๋”์ด์ƒ for๋ฌธ์ด ๋๋‚ ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐํ•˜์ง€ ์•Š์•„๋„ ๋  ๊ฒƒ์ด๋‹ค. ์‹ค์ œ๋กœ ์ฝ”๋“œ๋ฅผ ๋ณ€๊ฒฝํ•œ ํ›„์—๋Š” ํ•œ๋ฒˆ๋„ Lock์ด ๊ฑธ๋ฆฌ์ง€ ์•Š์•˜๋‹ค.