19,800원
다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 미해결재고시스템으로 알아보는 동시성이슈 해결방법
stock decrease에서 synchronized 키워드가 없어도 비관적 락 이후 부터는 동시성문제는 해결이 되는건가요?
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.
- 미해결재고시스템으로 알아보는 동시성이슈 해결방법
pessimistic lock 관련 질문입니다.
pessimistic lock을 구현하실때 PessimisticLockStockService 클래스의 decrease 메소드에 @Transactional을 붙이셨는데 이유를 알 수 있을까요?저는 @Transcational 어노테이션을 decrease 메소드에 붙이지 않으면 실행시 org.springframework.dao.InvalidDataAccessApiUsageException: no transaction is in progress; nested exception is javax.persistence.TransactionRequiredException: no transaction is in progress이런 에러가 발생합니다. 해당 어노테이션을 찾아는 봤는데 pessimistic lock을 메소드에 걸었을때 transactional을 걸어야한다 이런 자료는 찾지 못해서요. 답변 부탁드립니다. 감사합니다. 참고로 @Transactional 어노테이션을 걸어주지 않으면 아래 사진처럼 quantity가 하나도 감소하지않은 100개가 결과값으로 출력됩니다.
- 해결됨재고시스템으로 알아보는 동시성이슈 해결방법
분산락의 정의가 궁금합니다.
인터넷을 찾아봐도 분산락은 언제 쓴다. 이 정도의 얘기만 나오고 그래서 분산락이 무엇인지에 관해서는 안 나오더라구요 !Redis를 이용한 방식은 분산락이고, 네임드락을 이용한 방식도 분산락이라고 부르는 것 같긴한데, 대체 분산락이란 무엇인가요?무엇을 분산한다는 것인가요?비관적 락은 분산 락인가요?
- 해결됨재고시스템으로 알아보는 동시성이슈 해결방법
비관적 락과 update product set stock = stock -1 where id = 1의 차이
update product set stock = stock -1 where id = 1 이렇게 할 경우 읽는 작업과 쓰는 작업이 원자적으로 이루어지고, 이 쿼리가 커밋하기 전까지는 다른 update 쿼리는 블락되기 때문에 비관적 락과 다른 점이 없다고 생각되는데요.제가 잘못 생각한 부분이 있을까요?
- 해결됨재고시스템으로 알아보는 동시성이슈 해결방법
Redis를 이용한 방식이 MySQL을 이용한 방식보다 느리지 않나요?
제가 생각하기로는 Redis를 이용한 방식은 서버 -> Redis서버 -> MySQL 이렇게 두 번 접근하게 되니 네트워크 타는 시간 때문에 당연히 더 느릴 것이라고 생각했거든요비관적 락을 이용한다면서버 -> MySQL 이렇게 바로 접근한 후에 lock이 풀릴 때까지 기다렸다가 바로 작업을 수행하니 더 빠르지 않나요?
- 미해결재고시스템으로 알아보는 동시성이슈 해결방법
10개가 되어야한다가 아니라 0개가 되어야한다 아닌가요?
재고시스템 만들어보기 - 문제점 3분 15초에 "우리가 원하는값은 10개가 되어야하는데" 라고 하셨는데 10개가 아니라 0개가 맞는것같아서요. 혹시 해당부분 답변해주실 수 있으실까요?
- 미해결재고시스템으로 알아보는 동시성이슈 해결방법
안녕하세요! Pessimistic lock 관련 질문이 있습니다.
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.안녕하세요 강사님!우선 좋은 강의 만들어주신 점 감사드립니다.다름이 아니라 강의에서 소개해주신대로 Pessimistic lock을 적용해서테스트 코드를 돌리는데 다음과 같은 에러가 떠서요 ㅜㅜ혹시 해결책에 대해 질문드려도 괜찮을까요?감사합니다!
- 미해결재고시스템으로 알아보는 동시성이슈 해결방법
saveansflush를 호출하시는 이유가 있나요?
궁금합니다
- 미해결재고시스템으로 알아보는 동시성이슈 해결방법
redis를 단순히 락 용도로 사용하지 않고..
redis를 단순히 락 용도로 사용하지 않고 redis에 재고수량을 저장 후 관리하는 방법도 사용하는 걸로 알고 있는데요.이런 방법은 별로인가요?
- 미해결재고시스템으로 알아보는 동시성이슈 해결방법
실패 시 반복 시도 하는 이유
optimisticlock을 사용 하는 경우엔 while 문으로 반복 시도를 하는데namedlock은 왜 재시도를 하지 않는지 궁금합니다.
- 미해결재고시스템으로 알아보는 동시성이슈 해결방법
동시성 제어 이슈
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를 채택하고 있다면 왜 강의에서 이용한 테스트코드는 무결성이 지켜지지 않는건가요?
- 미해결재고시스템으로 알아보는 동시성이슈 해결방법
서비스내에서 서비스 호출시
안녕하세요. :-) 좋은 강의 잘 듣고 있습니다. 궁금한 것이 있어 문의드립니다.Point를 취득시, 조건이 있는데. 여기서 동시성 이슈가 발생하여 redisson을 활용해서 풀어보려고 합니다.현재 PointService.addPoint 라는 메서드를 다른 서비스의 메서드에서 호출하여 사용하고 있습니다.Point취득 시 조건은 같은 type, id의 데이터 입력이 있었는지 확인 후. insert인데요. (db unique key로 풀수가 없었습니다.)Fasade에 락 로직을 넣어 PointService.addPoint 를 감싸고. 해당Fasade.addPoint를 다른 서비스의 메서드에서 호출했는데요. (예: AService.b 내부에서 Fasade.addPoint 호출) 동시성 이슈가 해결되지 않습니다. ( 현재 각 서비스 메서드에 @Transaction이 붙어있습니다.)로그를 보면, 락을 획득한 순서대로 진행이되는데. 2번째 락 thread에서 호출한 데이터가 1락 thread에서 업데이트한 데이터가 아닙니다.addPoint를 호출한 서비스 메서드의(AService.b) 트랜잭션이 끝나지 않아, db에 commit이 안된건가. 하고 pointRepogitory.save -> pointRepogitory.saveAndFlush로 해봤는데. 반드시 하나만 들어가야할 데이터가 꼭 2개가 들어갑니다.원인이 뭔지 모르겠습니다.pointService가 실패하면 AService.b로직을 rollback해야하니 commit을 하는게 아닌 것도 같구요.동시성 이슈가 발현될 만한건 addPoint에서인데요. 락을 상위 로직으로 다 올려야하는걸까요?addPoint를 호출하는 곳마다 락 로직으로 감싸주는게 맞는건지 다른 방법은 없는지 궁금합니다.제가 지금 더 확인해야할 키워드가 무엇인지 문의드립니다.동시성 이슈에 고민이 많았는데. 강의가 생겨 너무 좋습니다. 답변 부탁드립니다. 감사합니다.
- 미해결재고시스템으로 알아보는 동시성이슈 해결방법
OptimisticLock 관련 질문이 있습니다.
안녕하세요 좋은 수업 올려주셔서 감사합니다.현재 Test를 돌리게 되면 99 에서 무한 루프에 빠지게 됩니다.version 이 업데이터 되지 않고 실행이되어 여러 질문 게시판에 올려진 문제중 하나인 core 갯수 문제인지 했느데 그것 또한 되지 않아 말씀 질문 드립니다.https://github.com/Eco-Min/-concurrency_issue.git 2022-10-04 01:28:05.898 DEBUG 7468 --- [ Test worker] org.hibernate.SQL : insert into stock (product_id, quantity, version) values (?, ?, ?)Hibernate: insert into stock (product_id, quantity, version) values (?, ?, ?)2022-10-04 01:28:05.907 TRACE 7468 --- [ Test worker] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [BIGINT] - [1]2022-10-04 01:28:05.907 TRACE 7468 --- [ Test worker] o.h.type.descriptor.sql.BasicBinder : binding parameter [2] as [BIGINT] - [100]2022-10-04 01:28:05.907 TRACE 7468 --- [ Test worker] o.h.type.descriptor.sql.BasicBinder : binding parameter [3] as [BIGINT] - [0]2022-10-04 01:28:05.996 DEBUG 7468 --- [pool-1-thread-2] org.hibernate.SQL : select stock0_.id as id1_0_, stock0_.product_id as product_2_0_, stock0_.quantity as quantity3_0_, stock0_.version as version4_0_ from stock stock0_ where stock0_.id=?Hibernate: select stock0_.id as id1_0_, stock0_.product_id as product_2_0_, stock0_.quantity as quantity3_0_, stock0_.version as version4_0_ from stock stock0_ where stock0_.id=?2022-10-04 01:28:05.997 TRACE 7468 --- [pool-1-thread-2] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [BIGINT] - [1]2022-10-04 01:28:06.021 DEBUG 7468 --- [pool-1-thread-2] org.hibernate.SQL : update stock set product_id=?, quantity=?, version=? where id=? and version=?Hibernate: update stock set product_id=?, quantity=?, version=? where id=? and version=?2022-10-04 01:28:06.022 TRACE 7468 --- [pool-1-thread-2] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [BIGINT] - [1]2022-10-04 01:28:06.022 TRACE 7468 --- [pool-1-thread-2] o.h.type.descriptor.sql.BasicBinder : binding parameter [2] as [BIGINT] - [99]2022-10-04 01:28:06.022 TRACE 7468 --- [pool-1-thread-2] o.h.type.descriptor.sql.BasicBinder : binding parameter [3] as [BIGINT] - [1]2022-10-04 01:28:06.023 TRACE 7468 --- [pool-1-thread-2] o.h.type.descriptor.sql.BasicBinder : binding parameter [4] as [BIGINT] - [1]2022-10-04 01:28:06.023 TRACE 7468 --- [pool-1-thread-2] o.h.type.descriptor.sql.BasicBinder : binding parameter [5] as [BIGINT] - [0]2022-10-04 01:28:06.026 DEBUG 7468 --- [pool-1-thread-2] org.hibernate.SQL : select version as version_ from stock where id =?Hibernate: select version as version_ from stock where id =?2022-10-04 01:28:06.026 DEBUG 7468 --- [pool-1-thread-1] org.hibernate.SQL : select stock0_.id as id1_0_, stock0_.product_id as product_2_0_, stock0_.quantity as quantity3_0_, stock0_.version as version4_0_ from stock stock0_ where stock0_.id=?Hibernate: select stock0_.id as id1_0_, stock0_.product_id as product_2_0_, stock0_.quantity as quantity3_0_, stock0_.version as version4_0_ from stock stock0_ where stock0_.id=?2022-10-04 01:28:06.027 TRACE 7468 --- [pool-1-thread-2] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [BIGINT] - [1]2022-10-04 01:28:06.027 TRACE 7468 --- [pool-1-thread-1] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [BIGINT] - [1]2022-10-04 01:28:06.030 DEBUG 7468 --- [pool-1-thread-1] org.hibernate.SQL : update stock set product_id=?, quantity=?, version=? where id=? and version=?Hibernate: update stock set product_id=?, quantity=?, version=? where id=? and version=?2022-10-04 01:28:06.031 TRACE 7468 --- [pool-1-thread-1] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [BIGINT] - [1]2022-10-04 01:28:06.031 TRACE 7468 --- [pool-1-thread-1] o.h.type.descriptor.sql.BasicBinder : binding parameter [2] as [BIGINT] - [99]2022-10-04 01:28:06.031 TRACE 7468 --- [pool-1-thread-1] o.h.type.descriptor.sql.BasicBinder : binding parameter [3] as [BIGINT] - [1]2022-10-04 01:28:06.031 TRACE 7468 --- [pool-1-thread-1] o.h.type.descriptor.sql.BasicBinder : binding parameter [4] as [BIGINT] - [1]2022-10-04 01:28:06.032 TRACE 7468 --- [pool-1-thread-1] o.h.type.descriptor.sql.BasicBinder : binding parameter [5] as [BIGINT] - [0]
- 미해결재고시스템으로 알아보는 동시성이슈 해결방법
Redis 분산락 질문
안녕하세요. 일단 좋은 강의 잘 봤습니다 :) 한 가지 궁금한 점이 있는데요. Redis의 Redisson을 사용할 때StockService의 decrease() 메서드에 Transaction 어노테이션을 걸어두면 비관적락 + 레디스의 분산락을 동시에 사용하면 오히려 기대했던 성능이 더 안나올 수도 있지 않나요?Transaction 어노테이션을 쓰려면 Mysql의 lock 기능을 쓰는게 좋을까요?저도 잘 알지못하지만 이번에 이 동시성 강의를 듣고 찾아보다가 궁금해서 질문드립니다!
- 미해결재고시스템으로 알아보는 동시성이슈 해결방법
비관적 락에 대한 질문.
1.특정 row 락이 아닌 service 로직에 비관적 락을 걸어서 사용하는 경우도 있나요? 2.동시에 중복 저장을 막기 위해서 비관적 락을 통해 막을 수 있을까요?
- 미해결재고시스템으로 알아보는 동시성이슈 해결방법
redis 관련 질문 드립니다
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.강사님 쉽고 깔끔한 강의 감사드립니다다른 좋은 강의 부탁드립니다강의 듣고 난후 궁금한 사항 질문 드립니다.. 1.레디스 레튜스, 레디슨 사용시 서버가 장애 발생으로 갑자기 죽었을때는 락을잡고 관리하던 항목들은 자동으로 사라지는건가요 어떻게 되나요? 2.강사님이 경험하신 레디스 레튜스, 레디슨 를 실무 사례에 적용할때 어떤경우에 적용해보셨는지 사례 몇가지를 예시로 알려주세요..
- 미해결재고시스템으로 알아보는 동시성이슈 해결방법
질문있습니다
트랜잭션 어노테이션을을 서비스에서 걸어줬는데 왜 동시성 이슈가 발생하나요 ?
- 미해결재고시스템으로 알아보는 동시성이슈 해결방법
저도 낙관락쪽 테스트케이스 돌리면 무한루프 빠지는데 봐주실 수 있으신가요?
도움 부탁드립니다. (_ _)https://github.com/KIYOUNGYI/stock
- 미해결재고시스템으로 알아보는 동시성이슈 해결방법
서비스 로직에서 saveAndFlush 질문입니다.
안녕하세요. 먼저 알차고 좋은 강의 만들어 주셔서 감사하단 말씀을 드리고 싶습니다 ㅎㅎ 강의를 보다보니 서비스 로직에서 saveAndFlush 를 해주고 있는데 @Transactional 어노테이션이 있어서 디비에 반영이 잘 될거 같은데 saveAndFlush 를 해주는 이유가 따로 있을까요?그리고 저는 보통 save 를 사용했는데 saveAndFlush 를 사용하는 다른 특별한 이유가 있는지 궁금합니다.
- 미해결재고시스템으로 알아보는 동시성이슈 해결방법
@Component와 @Service 중 어떤 어노테이션을 쓰는게 의미 상 명확할까요?
OptimisticLockStockFacade와 NamedLockStockFacade에 속한 메소드는 비슷한 기능을 수행하는 것 같은데 붙어있는 어노테이션이 다릅니다.@Component와 @Service는 기능상 차이는 없고 비즈니스 로직을 처리하는 클래스라는 의미를 주기 위해 @Service를 사용한다고 알고 있습니다.지난 강의의 OptimisticLockStockFacade 에는 @Service 를 붙이시고 이번 강의의 NamedLockStockFacade에는 @Component 를 붙이시는데 의도하신거라면 왜 다른 어노테이션을 붙이신건가요?