엔티티에는 4가지 상태가 존재한다.

엔티티 객체를 생성하고 Entity Manager 의 persist() 메서드를 호출하지 않은 상태이다.

Entity Manager 의 persist() 메서드를 호출해 Entity 객체를 영속성 컨텍스트에 저장한 상태이다.
Entity 객체가 영속성 컨텍스트에 의해 관리되는 상태이다.
영속 상태가 된다고 바로 DB에 쿼리가 날라가지 않는다. (즉, DB 저장 X)
트랜잭션의 commit 시점에 영속성 컨텍스트에 있는 정보들이 DB에 쿼리로 날라간다.
// 객체를 생성한 상태 (비영속)
Member member = new Member();
member.setId("member1");
member.setUsername("회원1");
EntityManager entityManager = entityManagerFactory.createEntityManager();
entityManager.getTransaction().begin();
// 객체를 저장한 상태 (영속)
entityManager.persist(member);
https://gmlwjd9405.github.io/2019/08/08/jpa-entity-lifecycle.html
영속성 컨텍스트에 저장되었다가 분리된 상태와 영속성 컨텍스트에서 지운 상태이다.
// 회원 엔티티를 영속성 컨텍스트에서 분리, 준영속 상태
entityManager.detach(member);
엔티티를 영속성 컨텍스트와 데이터베이스에서 삭제한다.
// 객체를 삭제한 상태(삭제)
em.remove(member);
영속 상태
entityManager.persist() 로 영속성 컨텍스트에 저장된 상태entityManager.find() 로 조회할 때 영속성 컨텍스트 1차 캐시에 없어서 DB에서 조회한 후 해당 Entity를 1차 캐시에 올라간 상태 (엔티티 매니저가 관리하는 상태)준영속 상태
JpaRepository 의 구현체인 SimpleJpaRepository 는 EntityManager 를 필드로 가진며 생성자 주입받아 싱글톤으로 사용한다.

싱글톤임으로 동시성 문제가 발생할 수 있기 때문에 스프링 프레임워크는 여기에 실제 EntityManager를 주입하는 것이 아니라, 실제 EntityManager를 연결해주는 가짜 EntityManager를 주입해둔다(proxy).
그렇다면 동일한 EntityManager 에 여러 Thread 가 접근해도 괜찮을까?
괜찮다.
내가 정리한 내용)
gpt)

@Transactional 을 Service 단에서 선언하지 않으면 각각 Repository 코드 내부에 존재하는 @Transactional 을 사용해 별도의 트랜잭션으로 동작한다.

만약 아래와 같은 코드를 실행하는데 하나의 트랜잭션으로 묶여있지 않다면
Member savedMember = memberRepository.save(member); // -> 트랜잭션 Tx1, 영속성 컨텍스트1
Member foundMember = memberRepository.findById(member.getId()).get();// -> 트랜잭션 Tx2, 영속성 컨텍스트2
두 객체를 비교할 시 다른 객체로 판별한다.
https://gmlwjd9405.github.io/2019/08/08/jpa-entity-lifecycle.html