묻고 답해요
141만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨MySQL 성능 최적화
ssd 에선 innodb_flush_neighbors을 0으로 하면 될까요?
hdd에서 유용한것 같아서 ssd를 사용하면 1이나 2로 안해도 성능상 영향이 없는걸로 봐도 될까요?
-
해결됨자바 ORM 표준 JPA 프로그래밍 - 기본편
em.flush 발생 시점에 대한 부가적인 질문
오랜만에 관련된 업무 진행하다가 발생한 궁금점에 대하여 질문드리게 되었습니다. 우선 한 트랜젝션의 영속성 컨텍스트에 대하여 쓰기 지연 저장소에 쌓인 쿼리가 flush() 되는 경우는 다음 세 가지로 이해하였습니다. flush() 직접호출트랜젝션 commit()JPQL 직접 발생시, 해당 JPQL 발생 이전 다음과 같은 연관관계가 가정되어 있다고 해보겠습니다. public class Car{ @Id private Long id; } public class Wheel { @Id private Long id; @ManyToOne @JoinColumn(name = "car_id") private Car car; } Wheel 이 연관관계의 주인이며, Car 와 M:1 관계로 매핑되어 있습니다. 이 때, 다음과 같은 로직을 수행해보겠습니다. (1L 의 Wheel 이 2L 의 Car 에 매핑되어 있음) Wheel wheel = em.find(Wheel.class, 1L); wheel.setCar(null); // 1) em.createQuery("delete from Car c where c.id = :id") .setParameter("id", 2L) .exeucteUpdate(); // 2) 이와 같이 수행되었을 때, 1번 시점에서 영속성 컨텍스트에 보관중인 Wheel 의 Car 값이 변경되어 Update 쿼리가 발생하여 쓰기 지연 저장소에 저장되었을 것으로 추측합니다. 2번 시점은 위에서 말한 'flush 발생시점' 중 3번에 해당한다고 생각했습니다 (JPQL 직접 수행). 그렇다면 쓰기 지연 저장소에 쌓인 Update 쿼리가 나간 이후, 직접 수행하려는 Delete JPQL 을 발생시켜서 아무 문제 없이 수행되어야 하는거 아닌가 싶었는데, 위 로직은 FK 제약조건에 위배되어 수행되지 못합니다. 1번과 2번 사이에 강제로 em.flush() 를 진행해주면, 그제서야 update 쿼리가 발생한 뒤에 delte 쿼리가 발생하여 위 로직이 아무 에러 없이 수정되는 모습을 확인했습니다. 왜 이 상황에서는 flush 가 자동으로 발생하지 않나요? 열심히 찾아봤을 때... JPA 측에서 제공하는 3번 (JPQL 발생시 flush 됨) 에 대한 명확한 [기준] 은 제시하고 있지 않은 것으로 보이는데 맞을까요??
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
em.flush() & em.clear() 제가 이해하고 있는게 맞나요?
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용] em.flush와 em.clear를 하지 않았을 경우에 db에는 persist한 데이터가 저장되긴 하지만 iterator로 리스트를 출력했을때 내용이 나오지 않아서 그 이유를 제가 올바르게 이해한건지 궁금합니다! em.fluch(); 로 영속성 컨텍스트에 있는 쿼리를 db로 날린 후 em.clear(); 하여 영속성 컨텍스트를 비우면 em.find()로 조회했을 때 1차캐시가 아닌 db에서 값을 찾아오기 때문에 findMember에 해당하는 팀의 회원리스트를 받아 올 수 있다. Team team = new Team(); team.setName("TeamA"); em.persist(team); Member member1 = new Member(); member1.setName("member1"); member1.setTeam(team); em.persist(member1); Member member2 = new Member(); member2.setName("member2"); member2.setTeam(team); em.persist(member2); em.flush(); // 영속성 컨텍스트에 있는 쿼리를 db로 날림 em.clear(); // 영속성 컨텍스트를 비움 Member findMember = em.find(Member.class, member1.getId()); // db에서 값을 가져온다. System.out.println("Team = " + findMember.getTeam().getName()); List<Member> members = findMember.getTeam().getMembers(); //양방향 연관관계 for (Member m : members) { System.out.println("m = : " + m.getName()); }
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
em.flush, em.clear에 관한 질문입니다
강의에서 영속성 컨텍스트에 있는 데이터를 데이터베이스에 보내기 위해 flush하고 그리고 영속성 컨텍스트를 비우기 위해 clear한 후 em.find하여 영속성 컨텍스트가 비워졌으니 데이터베이스에서 값을 가져오는 것은 이해했습니다. 제가 알기로는 em.find가 영속성 컨텍스트에서 찾아보고 없으면 데이터베이스에서 데이터를 가져오는데 그러면 clear하지 않고 영속성 컨텍스트에서 자료 찾아오는 것과 무슨 차이가 있는지 모르겠습니다... 영속성 컨텍스트에도 같은 자료가 있으니 굳이 clear할 필요가 있나 생각이 듭니다. 답변 부탁드립니다.
-
미해결
테스트 코드 Transactional, flush
안녕하세요! jpa 수업듣고 혼자 공부하다가 궁금한 점이 생겨서 질문 남깁니다. @Repository@Transactional@RequiredArgsConstructorpublic class ItemRepositoryImpl implements itemRepository{ private final EntityManager em; @Override public void delete(Long itemId){// Item item=findOne(itemId);// em.remove(item); em.createQuery("delete from Item i where i.id = :id") .setParameter("id",itemId).executeUpdate(); } @RunWith(SpringRunner.class)@SpringBootTest@Transactionalpublic class ItemRepositoryTest { @Autowired ItemRepository itemRepository; @Autowired private EntityManager em; private User user; private Item item; @Test public void delete(){ Long itemId= itemRepository.save(item); System.out.println(itemId); itemRepository.delete(itemId);// 1) System.out.println(itemRepository.findOne(itemId).getId()); Assertions.assertEquals(null,itemRepository.findOne(itemId)); } 테스트코드를 이렇게 작성하는 경우에는 delete가 다시 rollback되고 테스트 코드에서 1) 부분에서 rollback이 되고 itemRepository.findOne(itemId)가 itemId로 나오던데 @Transactional가 잘못 적용된 것인가요? jpql을 사용하는 경우 flush가 일어나서 flush 과정에서 commit이 일어나고 테스트 코드에서는 이 commit때문에 rollback이 일어나는 것 같은데 제가 생각한 것이 맞나요? 만약 제가 생각한 것이 맞다면 테스트 코드 부분에 1)에서 롤백이 일어나서 테스크코드 delete 메소드에서 save(item)부분도 롤백이 되서 itemRepository.delete(itemId)를 한 이후에는 find해도 null이 나와야하는데 그대로 itemId가 나오는 이유가 뭘까요? 주석처리한 것처럼 em.remove를 사용하면 테스트에 성공하는데 그 이유는 뭘까요ㅜㅜ
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
entityManager.flush() 호출을 하면 실제 데이터베이스에 반영이 되나요?
=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]1. entityManager.flush() 호출 시에 "쓰기 지연 SQL 저장소"에 저장된 (persist 된) 객체의 경우 외부의 h2-console 에서 조회 시에 조회되지 않는 것 같은데, 왜 그런지요? flush 이후에 아래의 System.out.println 에서 breakpoint 를 잡고, Member 테이블을 조회해 보면 여전히 "마지막의수혁"이라는 이름으로 조회가 되는데 "처음의수혁"이 flush 되어서 조회 되어야 하지 않을까 생각했습니다. flushMode 도 명시해 보았지만 효과는 없었습니다. // -- 6. 엔티티 변경 감지 (Dirty Checking)Member member = em.find(Member.class, 0L);Assert.isTrue(member.getName().equalsIgnoreCase("마지막의수혁"), "오류1");System.out.println(member.getName());member.setName("처음의수혁");em.persist(member);em.flush();System.out.println("여기서 Breakpoint 잡고 h2-console 조회");member.setName("마지막의수혁");tx.commit();System.out.println("종료");
-
미해결실전! Querydsl
벌크 연산 수행후 flush( ) 사용 질문
안녕하세요 강의 잘 듣고 있습니다!^^ 벌크 연산 수행후 영속성 컨텍스트와 DB의 값이 달라지기 때문에 em.flush( ), em.clear( ) 를 해주면 된다고 하셨는데 이미 DB에는 값이 저장 되었는데 flush( )를 해주는 이유가 있을까요? clear( )만 해주면 안되나요?
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
영속성 컨텍스트 1차 캐시가 비워지는 시점은 언제인가요?
안녕하세요, 영속성 컨텍스트 1차 캐시에 대한 질문이 있습니다. 새로운 트랜잭션이 시작되는 시점에서도 1차 캐시가 유지되는 건가요? 만약 맞다면 1차 캐시가 비워지는 시점이 언제인가요? 강의를 보면 영속성 컨텍스트 1차 캐시는 flush 시점(커밋 시점) 이후에도 내용을 유지한다고 합니다. 그렇다면 새로운 트랜잭션이 시작되는 시점에서도 1차 캐시가 유지되는 건지가 궁금하구요. 궁금한 이유는,새로운 트랜잭션이 시작되었는데도 이전 트랜잭션 시점의 데이터가 담긴 1차 캐시를 계속 바라보면 문제가 될 수 있을 것 같아서요. 답변해주시면 감사하겠습니다!
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
flush, clear 질문
안녕하세요. flush, clear를 호출하지 않았더니 members 리스트에 값이 들어오지 않아 질문 드립니다. 이전 강의에서 flush, clear를 호출하는 이유는 영속성 컨텍스트를 모두 지우고 Select 쿼리가 호출되는 것을 보기 위해 넣는다고 하셨는데요. 그래서 저는 flush, clear를 호출하지 않고 find를 호출해도 영속성 컨텍스트에서 값을 잘 찾아오기 때문에 호출하지 않고 양방향 예제를 작성하였습니다. 그런데 members에 값이 들어오지 않아서 혹시나 해서 flush, clear를 호출했더니 리스트가 잘 들어옵니다. 그런데 이 부분이 이해가 가지 않습니다. 위에서 persist하는 과정에 영속성 컨텍스트에 1차 캐시가 이뤄졌고 find를 통해 member도 잘 찾아왔는데 members는 왜 값이 들어오지 않을까요? 혹시 양방향 연관관계는 반드시 flush, clear를 호출 해줘야 하는건가요?