inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

재고시스템으로 알아보는 동시성이슈 해결방법

프로젝트 생성

동시성 제어 이슈

429

백승찬

작성한 질문수 1

0

package org.example;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

class Test implements Runnable {
    private Connection conn;

    Test(Connection conn) {
        this.conn = conn;
    }
    @Override
    public void run() {
            try(PreparedStatement pstmt = conn.prepareStatement("UPDATE stock SET quantity = quantity + 1 WHERE id = 1")) {
                pstmt.executeUpdate();
            } catch (SQLException e) {
                System.out.println("error");
            }
    }
}

public class Main {
    private static String address = "localhost";
    private static String port = "3306";
    private static String databaseName = "stock_example";
    private static String tableName = "stock";
    private static String user = "root";
    private static String password = "1234";
    private static String url = "jdbc:mysql://" + address + ":" + port + "/" + databaseName;

    public static void main(String args[]) {
        Connection[] conn = new Connection[100];
        Thread[] thread = new Thread[100];

        for ( int i = 0 ; i < 100 ; i++ ) {
            try {
                conn[i] = DriverManager.getConnection(url, user, password);
                thread[i] = new Thread(new Test(conn[i]));
            } catch (SQLException e) {
                System.out.println(e.getMessage());
            }
        }

        for ( int i = 0 ; i < 100 ; i++ ) {
            thread[i].start();
        }
    }
}

본 강의를 수강한 이후에 isolation level에 대해서 학습을 하면서 mysql은 기본적으로 repeatable read를 적용하고 있다는 것을 보았습니다.

그렇다면 따로 설정을 해주지 않더라도 동시성 문제가 해결되는 것은 아닌가 생각이 들어 위와 같은 코드를 통해서 테스틀 해보았습니다. 테스트 환경은 spring을 따로 사용하지 않았으면 gradle에 jdbc 의존성만 추가 해주고 진행하였습니다.

위의 코드에서 각각의 쓰레드가 stock의 수량에 대해서 1씩 증가하려는 코드이고 코드 실행 후 db에 수량을 확인하여 100개로 잘 나타는것을 확인하였습니다.

이 경우에는 왜 강의에서 진행하는 테스트와 달리 db의 무결성이 지켜지지 않는 문제가 발생하지 않는건가요? 또한 mysql은 repeatable read를 채택하고 있다면 왜 강의에서 이용한 테스트코드는 무결성이 지켜지지 않는건가요?

동시성 spring java

답변 1

2

최상용

백승찬님 안녕하세요.

예제로 작성해주신 UPDATE stock SET quantity = quantity + 1 WHERE id = 1 과 같은 쿼리로 실행할 시 정합성이 database 레벨에서 맞춰지기때문에 정합성이 맞습니다.

하지만 강의에서는 jpa 의 도움을 받아 쿼리를 작성합니다.

그렇기에 UPDATE stock SET quantity = quantity + 1 WHERE id = 1 과 같은 쿼리가 아닌 아래와 같은 쿼리가 실행하게 됩니다.

UPDATE stock SET quantity = 2 WHERE id = 1 

이 경우에는 수량을 application 레벨에서 맞춰지기 때문에 정합성이 어긋날 수 있습니다.

예시로는 강의에 나와있는 내용과 같습니다.

예제의 쿼리를 jpa 에서 발생하는 코드와 동일하게 변경한다면 동일하게 정합성이 깨질겁니다.

감사합니다.

레디선 테스트코드에서 채널이름은 없어도 되는건가요?

0

43

2

낙관적 락을 사용할 떄 차이점

0

120

2

동시성 검증 코드에 관한 문의

0

94

2

단일연산

0

70

2

낙관적락vs. 레디스락

0

108

2

안녕하세요. 레디슨 질문있습니다..!!

0

67

2

@Lock(OPTIMISTIC)이 필요한 이유

0

90

2

get_lock 의 timeout이 3000초 이던데 너무 긴거 아닌가요?

0

132

2

DataSource Hikari 사용 이유

0

147

2

saveAndFlush 사용 이유 문의

0

113

3

비관적 락 VS 네임드 락

0

160

3

application.yaml 에 redis 정보

0

99

2

왜 클래스 이름에 Facade 가 붙나요?

0

184

2

@Transactional 으로 인한 동시성 문제 발생 원인이 궁금합니다.

0

219

2

@modifying 이용한 동시성 제어

0

168

2

DB락과 분산락

0

260

2

NamedLock 테스트 실패

0

186

2

테스트에서 트랜잭션 어노테이션 질문 있습니다.

0

172

2

optimistic Lock 재시도 질문입니다.

0

230

2

낙관적 락 테스트 실패

0

239

2

오류?

0

1627

4

LettureLockStockFacadeTest에서 오류가 발생합니다.

1

268

2

Pessimistic Lock 전체 테스트 오류 문의

0

360

3

비관적 락 vs 레디스(Lettuce)락 비교 관련 질문

0

460

2