개요
거래 관리는 엔터프라이즈 응용 프로그램에 중요하며 비정상적인 상황이 발생하더라도 데이터 일관성을 보장 할 수 있습니다.
Spring Framework는 트랜잭션 관리에 대한 일관된 추상화를 제공하며 다음과 같이 특성을 제공합니다.
JTA (Java Transaction API), JDBC, Hibernate, JPA (Java Persistence API 및 JDO (Java Data Objects)와 같은 다양한 트랜잭션 API에 대한 일관된 프로그래밍 모델 제공
선언적 트랜잭션 관리, 특히 주석에 기초한 선언적 거래 관리를 지원하며 간단하고 사용하기 쉽습니다.
JTA와 같은 다른 트랜잭션 API보다 간단한 프로그래밍 트랜잭션 관리 API를 제공합니다.
스프링 데이터 액세스 추상화와 완벽한 통합
거래 관리 방법
Spring은 프로그램 거래 관리 및 선언 거래 관리의 두 가지 방법을 지원합니다.
프로그래밍 방식 트랜잭션 관리는 트랜잭션 템플릿을 사용하거나 기본 플랫폼 transactionManager를 직접 사용합니다. 프로그래밍 트랜잭션 관리의 경우 Spring은 TransactionTemplate를 사용하는 것이 좋습니다.
선언 거래 관리는 AOP에 구축됩니다. 본질은 전후에 메소드를 가로 채고 대상 방법이 시작되기 전에 트랜잭션을 작성하거나 추가하는 것입니다. 대상 방법을 실행 한 후 거래는 실행 상황에 따라 제출되거나 롤백됩니다. 선언 거래의 가장 큰 장점은 프로그래밍 방식으로 트랜잭션을 관리 할 필요가 없으므로 비즈니스 로직 코드에서 거래 관리 코드를 도난 할 필요가 없다는 것입니다. 구성 파일 (또는 @Transactional Annotation)에서 관련 트랜잭션 규칙 선언을 작성하면 거래 규칙을 비즈니스 로직에 적용 할 수 있습니다.
분명히, 선언적 거래 관리는 프로그램 거래 관리보다 낫습니다. 이는 Spring이 옹호하는 비 침습적 개발 방법입니다. 선언적 거래 관리는 비즈니스 코드를 오염에서 자유롭게 유지합니다. 일반적인 POJO 객체는 주석을 추가하여 완전한 트랜잭션 지원을 얻을 수 있습니다. 프로그래밍 거래와 비교할 때 선언적 거래의 유일한 단점은 후자의 가장 훌륭한 세분성이 방법 수준에서만 작용할 수 있으며 프로그램 트랜잭션이 코드 블록 수준에서 작용할 수 있으므로 달성 할 수 없다는 것입니다. 그러나 이러한 요구 사항이 있더라도 거래 관리가 필요한 코드 블록과 같은 많은 해결 방법이 있습니다.
선언적 거래 관리에 일반적으로 사용되는 두 가지 방법이 있습니다. 하나는 TX 및 AOP 네임 스페이스를 기반으로 한 XML 구성 파일이고 다른 하나는 @transactional 주석을 기반으로합니다. 분명히, 주석 기반 방법은 더 간단하고 사용하기 쉽고 더 상쾌합니다.
자동 커밋 (자동 커밋) 및 연결이 닫힐 때 자동으로 제출할지 여부
자동 제출
기본적으로 데이터베이스는 자동 제출 모드입니다. 각 진술은 별도의 거래에 있습니다. 이 명령문의 실행이 완료되면 실행이 성공하면 거래가 암시 적으로 제출됩니다.
실행이 실패하면 트랜잭션이 암시 적으로 롤백됩니다.
일반적인 트랜잭션 관리의 경우 관련 작업 세트가 트랜잭션에 있으므로 데이터베이스의 자동 커밋 모드를 끄 려야합니다. 그러나 우리는 이것에 대해 걱정할 필요가 없습니다. Spring은 기본 연결의 자동 커밋 기능을 False에 설정합니다.
org/springframework/jdbc/dataSource/dataSourcetransactionManager.java
// 필요한 경우 수동 커밋으로 전환합니다. 이것은 일부 jdbc 드라이버에서 매우 비싸기 때문에 // 우리는 불필요하게 수행하고 싶지 않습니다 (예 : 명시 적으로 // 이미 설정하도록 연결 풀을 구성한 경우) .if (con.getautocommit ()) {txobject.setmustrestoreautocommit (true); if (logger.isdebugenabled ()) {logger.debug ( "JDBC 연결 스위칭 [" + con + "] 수동 커밋"); } con.setAutocommit (false);}일부 데이터 연결 풀은 자동 트랜잭션 커밋을 끄는 설정을 제공합니다. 이는 연결 풀을 설정할 때 끄는 것이 가장 좋습니다. 그러나 C3P0 은이 기능을 제공하지 않으며 스프링에만 의존하여 설정할 수 있습니다.
JDBC 사양은 연결 객체가 설정되면 자동 커밋 모드에 있어야하며 DBMS의 기본값 인 자동 커밋 모드에 있어야하며 필요한 경우 자동 커밋을 명시 적으로 꺼야합니다. C3P0 은이 사양을 준수하며 클라이언트 코드가 필요한 제출 모드를 명시 적으로 설정할 수 있습니다.
연결이 닫힐 때 자동으로 제출할지 여부
연결이 닫히면 커밋되지 않은 트랜잭션이 있으면 무엇을 처리해야합니까? JDBC 사양은 C3P0의 기본 정책이 커밋되지 않은 트랜잭션을 롤백하는 것임을 언급하지 않습니다. 이것은 올바른 전략이지만이 문제에 대해 JDBC 드라이버 제공 업체간에 동의는 없습니다.
C3P0의 AutocommitonClose 속성은 기본적으로 False이므로 이동하지 않아도됩니다. 또는이 속성을 명시 적으로 False로 설정할 수 있습니다.
주석 기반 선언 트랜잭션 관리 구성
Spring-Servlet.xml
<!-트랜잭션 지원-> <!-PlatformTransactionMnager-> <bean id = "txmanager"> <property name = "dataSource"ref = "dataSource" /> < /bean> <!-트랜잭션 주석 지원을 활성화합니다.
Spring-Servlet.xml에 TX 네임 스페이스를 추가하십시오
... xmlns : tx = "http://www.springframework.org/schema/tx"xmlns : aop = "http://www.springframework.org/schema/aop"xsi : schemalocation = "... http : //www.spramframwork.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd ...
Mybatis는 추가 구성없이 스프링 트랜잭션 관리에 자동으로 참여합니다. org.mybatis.spring.sqlsessionfactorybean이 참조하는 데이터 소스가 DataSourcetransactionManager에서 참조 된 데이터 소스와 일치하는 한, 그렇지 않으면 트랜잭션 관리가 작동하지 않습니다.
또한 종속성 패키지 Aopalliance.jar를 다운로드하여 Web-Inf/Lib 디렉토리에 넣어야합니다. 그렇지 않으면 스프링이 초기화되면 예외 가보고됩니다.
java.lang.noclassdeffounderror : org/aopalliance/intercept/methodinterceptor
스프링 트랜잭션 기능
봄의 모든 트랜잭션 관리 정책 클래스
public Interface PlatformTransactionManager {TransactionStatus getTransaction (TransactionDefinition Definition)은 TransactionException을 던집니다. void Commit (TransactionStatus 상태)는 TransactionException을 던집니다. 무효 롤백 (TransactionStatus 상태)은 TransactionException을 던집니다.}TransactionDefinition 인터페이스는 다음 특성을 정의합니다.
거래 격리 수준
격리 수준은 여러 동시 거래 사이의 격리 정도를 나타냅니다. 격리 수준을 나타내는 5 개의 상수는 TransactionDefinition 인터페이스에서 정의됩니다.
TransactionDefinition.isolation_default : 기본 값이므로 기본 데이터베이스에 사용되는 기본 격리 레벨을 나타냅니다. 대부분의 데이터베이스의 경우이 값은 일반적으로 TransactionDefinition.isolation_read_committed입니다.
TransactionDefinition.isolation_read_uncommitted :이 격리 수준은 한 트랜잭션이 다른 트랜잭션으로 수정 된 데이터를 읽을 수 있지만 아직 커밋되지 않았 음을 나타냅니다. 이 수준은 더러운 읽기, 반복적 인 독서 및 팬텀 독서를 방해하지 않으므로이 격리 수준은 거의 사용되지 않습니다. 예를 들어 PostgreSQL에는 실제로이 레벨이 없습니다.
TransactionDefinition.isolation_read_committed :이 격리 수준은 하나의 트랜잭션이 다른 트랜잭션에 의해 커밋 된 데이터 만 읽을 수 있음을 의미합니다. 이 수준은 더러운 읽기를 방지하며, 이는 대부분의 경우 권장 값이기도합니다.
TransactionDefinition.isolation_Repeatable_Read :이 격리 수준은 트랜잭션이 프로세스 전체에서 여러 번 쿼리를 실행할 수 있고 반환 된 레코드가 매번 동일하다는 것을 나타냅니다. 이 수준은 더럽고 반복 할 수없는 판독 값을 방지합니다.
TransactionDefinition.isolation_serializable : 모든 트랜잭션은 하나씩 순서대로 실행되므로 트랜잭션 간의 간섭 가능성이 없도록,이 수준은 더러운 읽기, 반복 불가능한 판독 및 팬텀 판독을 방지 할 수 있습니다. 그러나 이것은 프로그램의 성능에 심각한 영향을 미칩니다. 이 레벨은 일반적으로 사용되지 않습니다.
거래 커뮤니케이션 행동
소위 거래 전파 동작은 현재 트랜잭션이 시작되기 전에 트랜잭션 컨텍스트가 이미 존재하는 경우 트랜잭션 방법의 실행 동작을 지정할 수있는 몇 가지 옵션이 있다고 말합니다. TransactionDefinition 정의에는 전파 동작을 나타내는 다음 상수가 포함됩니다.
TransactionDefinition.propagation_required : 트랜잭션이 현재 존재하는 경우 거래에 가입하십시오. 현재 거래가없는 경우 새 트랜잭션을 작성하십시오. 이것이 기본값입니다.
TransactionDefinition.propagation_requires_new : 새로운 거래를 생성하고 거래가 현재 존재하면 현재 트랜잭션이 중단됩니다.
TransactionDefinition.propagation_supports : 현재 거래가있는 경우 거래에 가입하십시오. 현재 거래가없는 경우 비 트랜잭션 방식으로 계속 실행됩니다.
TransactionDefinition.propagation_not_supported : 비 트랜잭션 방식으로 실행되며 현재 거래가 존재하면 현재 트랜잭션이 중단됩니다.
TransactionDefinition.propagation_never : 비 트랜잭션 방식으로 실행되며 트랜잭션이 현재 존재하는 경우 예외를 발생시킵니다.
TransactionDefinition.propagation_mandatory : 현재 거래가있는 경우 거래에 가입하십시오. 현재 거래가없는 경우 예외가 발생합니다.
TransactionDefinition.propagation_nested : 트랜잭션이 현재 존재하는 경우 현재 트랜잭션의 중첩 거래로 실행되도록 트랜잭션이 생성됩니다. 거래가없는 경우 값은 TransactionDefinition.propagation_required와 동일합니다.
거래 시간 초과
소위 트랜잭션 타임 아웃은 트랜잭션에서 허용되는 최대 시간을 나타냅니다. 시간 제한이 초과되었지만 트랜잭션이 완료되지 않은 경우 트랜잭션이 자동으로 롤백됩니다. TransactionDefinition에서 타임 아웃은 Int의 값으로 표시되고 해당 단위는 초입니다.
기본 설정은 기본 트랜잭션 시스템의 시간 초과 값입니다. 기본 데이터베이스 트랜잭션 시스템이 시간 초과 값을 설정하지 않으면없고 시간 초과 제한이 없습니다.
트랜잭션 읽기 전용 속성
읽기 전용 트랜잭션은 클라이언트 코드가 읽기 전용이지만 데이터를 수정하지 않는 상황에서 사용됩니다. 읽기 전용 트랜잭션은 Hibernate를 사용할 때와 같은 특정 시나리오에서 최적화에 사용됩니다.
기본값은 읽기 및 쓰기 트랜잭션입니다.
스프링 트랜잭션 롤백 규칙
Spring Transaction Manager에게 거래를 롤백하도록 지시하는 권장 방법은 현재 거래의 맥락에서 예외를 던지는 것입니다. Spring Transaction Manager는 처리되지 않은 예외를 포착 한 다음 규칙에 따라 예외를 발생시키는 거래를 롤백할지 여부를 결정합니다.
기본적으로, 스프링은 예외가 체크되지 않은 예외 인 경우에만 트랜잭션을 롤백합니다. 즉, 예외는 runtimeexception의 서브 클래스 (오류도 트랜잭션 롤백을 유발합니다)이며 점검 된 예외는 트랜잭션 롤백을 유발하지 않습니다.
확인 된 예외를 포함하여 예외가 발생할 때 트랜잭션을 명시 적으로 구성 할 수 있습니다. 예외가 발생할 때 롤백되지 않는 거래를 명확하게 정의 할 수도 있습니다.
또한 setRollbackonly () 메소드를 프로그래밍 방식으로 사용하여 트랜잭션을 롤백해야 함을 나타냅니다. setrollbackonly ()를 호출 한 후 할 수있는 유일한 것은 롤백입니다.
@transactional 주석
@Transactional 속성
| 재산 | 유형 | 설명하다 |
|---|---|---|
| 값 | 끈 | 옵션 Qualifier Descriptor, 사용할 트랜잭션 관리자를 지정합니다 |
| 번식 | 열거 : 전파 | 선택적 트랜잭션 전파 동작 설정 |
| 격리 | 열거 : 격리 | 선택적 트랜잭션 격리 수준 설정 |
| 준비 적 | 부울 | 읽기 및 쓰기 또는 읽기 전용 거래, 기본 읽기 및 쓰기 |
| 시간 초과 | int (몇 초 만에 세분화) | 거래 시간 초과 설정 |
| 롤백 | 클래스 객체 배열은 던질 수있는 곳에서 상속되어야합니다 | 트랜잭션 롤백을 유발하는 예외 클래스 배열 |
| RollbackforClassName | 클래스 이름 배열은 던질 수있는 곳에서 상속되어야합니다 | 트랜잭션 롤백을 유발하는 예외 클래스 이름 배열 |
| Norollbackfor | 클래스 객체 배열은 던질 수있는 곳에서 상속되어야합니다 | 트랜잭션 롤백을 유발하지 않는 예외 클래스 배열 |
| norollbackforclassName | 클래스 이름 배열은 던질 수있는 곳에서 상속되어야합니다 | 트랜잭션 롤백을 유발하지 않는 예외 클래스 이름 배열 |
용법
@Transactional은 인터페이스, 인터페이스 방법, 클래스 및 클래스 방법에서 작동 할 수 있습니다. 수업에서 행동 할 때, 클래스의 모든 공개 방법에는 해당 유형의 거래 속성이 있습니다. 동시에, 우리는 메소드 레벨 에서이 주석을 사용하여 클래스 수준 정의를 무시할 수 있습니다.
@transactional 주석은 인터페이스, 인터페이스 메소드, 클래스 및 클래스 메소드에 적용될 수 있지만 Spring은 인터페이스 기반 프록시를 사용할 때만 적용되므로 인터페이스 또는 인터페이스 메소드 에서이 주석을 사용하지 않는 것이 좋습니다. 또한 @transactional 주석은 Spring AOP의 특성에 의해 결정되는 공개 방법에만 적용되어야합니다. 보호, 비공개 또는 기본 가시성 방법에서 @Transactional 주석을 사용하는 경우 이는 무시되며 예외는 발생하지 않습니다.
기본적으로 외부의 메소드 호출 만 AOP 프록시에 의해 캡처됩니다. 즉, 클래스 내부 의이 클래스 내 다른 메소드를 호출하면 @Transactional 주석을 사용하여 호출 된 메소드가 수정 되더라도 트랜잭션 동작이 발생하지 않습니다.
@transactional (readonly = true) public class defaultfooservice는 fooservice {public foo getfoo (string fooname) {// do something} //이 설정 이이 메소드에 대한 우선 순위를 가지고 있습니다. // 메소드의 주석 속성은 클래스의 readonly = false = restagation = restagation에서 동일한 속성을 무시할 것입니다. UpdateFoo (foo foo) {// do do it}}요약
위의 내용은 봄에 @transactional 주석 사용에 대한이 기사의 해석의 모든 내용이며, 모든 사람에게 도움이되기를 바랍니다. 관심있는 친구는이 사이트의 다른 관련 주제를 계속 참조 할 수 있습니다. 단점이 있으면 메시지를 남겨 두십시오. 이 사이트를 지원해 주신 친구들에게 감사드립니다!