programing

@Transactional with Spring Data를 사용하는 방법

bestcode 2022. 9. 3. 13:20
반응형

@Transactional with Spring Data를 사용하는 방법

스프링 데이터, 휴지 상태, MySQL, JPA 프로젝트를 막 시작했습니다.수작업으로 쿼리를 작성할 걱정을 하지 않기 위해 spring 데이터로 전환했습니다.

는는의 i i of of 가 사용되고 있는 을 알 수 .@Transactional스프링 데이터를 사용할 때는 주석 없이 쿼리를 시도했으므로 필요하지 않습니다.

@Transactional주??

동작:

@Transactional
public List listStudentsBySchool(long id) {
    return repository.findByClasses_School_Id(id);
}

동작:

public List listStudentsBySchool(long id) {
    return repository.findByClasses_School_Id(id);
}

제로 무무 ?? ??? ????「 」의 @Repository 또는 주석@Transactional.

@RepositorySpring Data 인프라스트럭처에 의해 작성된 프록시가 인터페이스를 지원한다고 선언한 경우 예외 변환을 활성화하기 때문에는 전혀 필요하지 않습니다.따라서 스프링 데이터 저장소 인터페이스에서 이 주석을 사용해도 아무런 효과가 없습니다.

@Transactional-SimpleJpaRepository JPA 모듈의 경우 프록시를 지원하는 구현 클래스에 이 주석이 있습니다().그 이유는 두 가지입니다.첫 번째로 오브젝트를 유지 및 삭제하려면 JPA에서 트랜잭션이 필요합니다.따라서 우리는 트랜잭션이 실행 중인지 확인해야 하며, 이는 메서드에 다음과 같은 주석을 붙임으로써 수행됩니다.@Transactional

, 읽다, 읽다, 읽다, 읽다, 읽다, 읽다, 읽기 방법findAll() ★★★★★★★★★★★★★★★★★」findOne(…)를 하고 있다@Transactional(readOnly = true)한 것은 Transaction Infrastructure)에서 몇 .FlushMode로로 합니다.MANUAL .EntityManager그 이후에는 JDBC Connection에도 플래그가 설정되어 있기 때문에 그 레벨에서의 최적화가 한층 더 진행됩니다.

사용하는 데이터베이스에 따라 테이블 잠금을 생략하거나 실수로 트리거할 수 있는 쓰기 작업을 거부할 수도 있습니다. 이렇게 하다를 사용하는 것이 .@Transactional(readOnly = true)이 주석을 리포지토리 인터페이스에 쉽게 추가할 수 있는 쿼리 메서드에 대해 설명합니다. 플레인 「」을 .@Transactional그 인터페이스로 선언 또는 재인스톨 했을 가능성이 있는 조작 방법에 대응합니다.

의 저장소가 있는지 .@Transactional그렇지 않으면.

'의 는 사용할 수 .@Transactional추가해도 .@Transactional나중에 다른 테이블/리포지토리를 처리하는 서비스에 로직을 추가할 계획이라면 그 로직이 있는 지점이 있을 것입니다.

아니오'인에는 '아니오'를 .@Transactional격리 문제가 없는지, 예를 들어 아직 변환되지 않은 내용을 읽지 않았는지 확인해야 합니다.

--

일반적으로 저장소(crud 컬렉션 인터페이스)에 대해 말하는 경우:

  1. 아니요, @Transactional을 사용하면 안 됩니다.

왜 안 되는가: 저장소가 비즈니스 컨텍스트를 벗어나 전파 또는 격리(잠금 수준)에 대해 알 수 없다고 판단되는 경우.어떤 트랜잭션 컨텍스트에 관여할 수 있는지 추측할 수 없습니다.

저장소는 '비즈니스리스'입니다(그렇게 생각하시면).

저장소가 있다고 가정합니다.

class MyRepository
   void add(entity) {...}
   void findByName(name) {...}

비즈니스 로직이 있습니다.예를 들어 MyService라고 합니다.

 class MyService() {

   @Transactional(propagation=Propagation.REQUIRED, isolation=Isolation.SERIALIZABLE)
   void doIt() {
      var entity = myRepository.findByName("some-name");
      if(record.field.equal("expected")) {
        ... 
        myRepository.add(newEntity)
      }
   }

 }

를 들어, 이 ,, 우:MyService이치노

전파="Required두 메서드 - 이우 = "Required"로 됩니다.findByName() ★★★★★★★★★★★★★★★★★」add()="직렬화 가능"=" 가능누구할 수 합니다.시리얼화 가능"이라고 하면, 아무도 이것에 간섭할 수 없게 됩니다. & add()가 .get & add()에 되어 있는합니다.

그러나 일부 사용하고 수 를 들어 .MyRepository를 사용하고 합니다.예를 들어, 이 서비스는 다음과 같이 어떠한 트랜잭션에도 관여하지 않습니다.findByName()이 순간에 찾을 수 있는 것은 무엇이든 읽을 수 있는 제한에는 관심이 없습니다.

  1. 저장소를 항상 유효한 엔티티(더티 읽기 없음) 등을 반환하는 것으로 취급하면(사용자가 잘못 사용하지 않도록 함) YES라고 말할 수 있습니다.즉, 저장소는 다음과 같은 분리 문제(통상과 데이터의 일관성)에 대처해야 합니다.

add(newEntity) 엔티티가 이름을 가진 엔티티가 있다면, 모든 이.) 모든 것을 하나의 잠금 장치에 삽입합니다.(위의 서비스 수준에서 했던 것과 동일하지만 이 책임을 저장소로 이전하지는 않습니다.)

예를 들어, 같은 이름의 "진행 중" 상태(비즈니스 규칙)를 가진 태스크는 2개일 수 없습니다.

 class TaskRepository
   @Transactional(propagation=Propagation.REQUIRED, 
   isolation=Isolation.SERIALIZABLE)
   void add(entity) {
      var name = entity.getName()
      var found = this.findFirstByName(name);
      if(found == null || found.getStatus().equal("in-progress")) 
      {
        .. do insert
      }
   }
   @Transactional
   void findFirstByName(name) {...}

두 번째는 DDD 스타일의 저장소입니다.


다음과 같은 경우에는 더 많은 내용을 다루어야 할 것 같습니다.

  class Service {
    @Transactional(isolation=.., propagation=...) // where .. are different from what is defined in taskRepository()
    void doStuff() {
      taskRepository.add(task);
    }
  }

하면 됩니다.@Repository

그 이유는@Repository하기 위해 할는 "SQL" "Spring Excetion" "Spring Excetion" "뿐입니다.DataAccessException

또한 @Transactional 주석을 사용하여 레코드를 잠그고 다른 스레드/요구가 읽기를 변경하지 않도록 합니다.

는 용용 we we we we we we we we we@Transactional동시에 하나 이상의 엔티티를 작성/업데이트할 때 주석을 추가합니다.「 」를 가지는 가 있는 .@Transactional예외가 발생하면 주석이 이전 삽입물을 롤백하는 데 도움이 됩니다.

언급URL : https://stackoverflow.com/questions/10394857/how-to-use-transactional-with-spring-data

반응형