Spring의 트랜잭션 지원
봄 프로그램 및 선언적으로 나누어 두 개의 트랜잭션 관리 기능을 제공합니다.
编程式
수동으로 코딩 방법을 사용합니다, 커밋 또는 트랜잭션,보다 세분화 된,하지만 더 많은 문제를 롤백.声明式
: 포장 방법에 대한 주석 또는 클래스 또는 인터페이스, 거래 비 침습적 달성하는 방식으로,보다 편리하지만, 더 큰 입자 크기를 추가하여.
트랜잭션을 지원하는 데 필요한 데이터베이스의 사용, 그렇지 않으면 트랜잭션이 작동하지 않습니다 주목해야한다. MySQL의의 MyISAM 엔진은 트랜잭션을 지원하지 않기 때문에.
Spring 트랜잭션 구성
따라 추가
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
复制代码
트랜잭션 관리자 구성
<bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 如果使用基于注解的声明式事务,需要配置annotation-driven -->
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
复制代码
물론,의 transactionManager 트랜잭션은 dataSource 작동 코드 데이터 소스, 또는 그것을 어떻게 관리하는이어야한다.
의 프로그램 거래로
코드에서 시작, 커밋 또는 트랜잭션을 롤백 :
// 开始事务
TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
// 异常回滚,并不一定要在try...catch中
transactionManager.rollback(status);
// 提交事务
transactionManager.commit(status);
复制代码
일반적으로, 사용의 적절한 방법 :
TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
try {
// 进行需要处在同一事务中的数据库操作
......
// 正常结束,提交事务
transactionManager.commit(status);
} catch (SomeException) {
// 错误处理
......
// 回滚
transactionManager.rollback(status);
}
复制代码
선언적인 트랜잭션을 사용하여
직접 또는 클래스 메소드에 추가 @Transaction
의주의 사항 :
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, rollbackFor = Exception.class)
public int save(Info info) throws Exception {
复制代码
@Transaction
공통 파라미터 노트 :
전파 전파 거동
REQUIRED(默认值)
갖는 트랜잭션의 컨텍스트에서 실행해야합니다 : 없음 (외부 층) 거래하는 경우, 새 트랜잭션을 생성, 현재 존재하는 (외부 층) 트랜잭션이, 현재 (외부 층) 거래에 추가됩니다. 가장 일반적인 선택 (호출 방법 예외가 발생하면 다음 방법 및 호출 거래되는 방법은 롤백됩니다 전화).SUPPORTS
더 (외부 층) 트랜잭션이 비 트랜잭션 방식으로 실행되지 않을 경우, 현재의 (외부 층) 트랜잭션을 지원합니다.MANDATORY
아니오 (외층) 트랜잭션, 예외가 발생하지 않는 경우, 전류 (외층) 트랜잭션을 사용하도록 강요했다.REQUIRES_NEW
새 트랜잭션을 생성하고 트랜잭션에서 실행, 현재 제 1 전류 (외부 층) 거래 정지 (외부 층) 트랜잭션을 존재NOT_SUPPORTED
비 트랜잭션 방식으로 동작을 수행하는 단계 : 현재 계류중인 트랜잭션 (외층) 트랜잭션, 전류 (외층)을두고 존재한다.NEVER
비 트랜잭션 방법을 수행하려면 : 현재 (외부 층) 거래를 존재하는 경우 예외가 발생합니다.NESTED
중첩 된 방식으로 수행 : 트랜잭션이 롤백 경우 현재 존재 (외부 층) 트랜잭션은 중첩 실행은 독립적 후, 현재 (외부 층) 거래, 현재 (외부 층)에 영향을주지 않고, 자신의 거래를 배치 트랜잭션 롤백되어야한다하지 현재 (외층) 트랜잭션이 존재하는 경우, PROPAGATION.REQUIRED 유사한 동작이 수행되어로.
절연 격리 수준
DEFAULT
기본 데이터베이스 트랜잭션 격리 수준을 사용하여READ_UNCOMMITTED
아직 읽을 수 수정하고 더러운 읽기가 발생할 수 있습니다, 팬텀 읽기 및 비 반복 읽기READ_COMMITTED
제출 된 트랜잭션에서 읽을 수 더러운 읽기 방지 할 수 있지만 팬텀 비 반복 읽기, 읽기는 여전히 가능REPEATABLE_READ
데이터가 현재 트랜잭션 자체를 변형하지 않으면 동일한 필드가 동일의 복수의 결과를 판독한다. 방지 더러운 읽고, 반복 불가의 읽어 들여,하지만 팬텀은 여전히 발생할 읽기SERIALIZABLE
ACID는 완전히 그 읽어 들여, 반복 불가, 읽기 더러운 발생하지 않도록, 분리의 원칙을 준수하고, 팬텀은 읽지 만 가장 낮은 효율성.
읽어 내 전용 읽기 전용 트랜잭션
이 거래는 데이터를 읽을되지만 데이터는 읽기 트랜잭션이 작업이 트랜잭션 데이터베이스 엔진을 최적화하는 데 도움이 될 수 있습니다 읽기 전용으로 설정, 업데이트되지 않습니다 여부를 나타냅니다.
타임 아웃 시간 제한
초, 오랜 시간 동안 데이터베이스를 잠금하지 마십시오.
롤백 예외 클래스 rollbackFor
기본에만 런타임 예외 롤백으로 아래를 참조하십시오.
결함 선언적인 트랜잭션
내부 클래스 호출
동적 AOP 프록시의 방법으로 Spring의 선언적 트랜잭션, 그것은 트랜잭션 프록시 클래스의 실현, 원래 클래스의 차이를 생성합니다. 상황을 고려 :
- 업무를 선언하지 않는 클래스 A의 서비스 방법
- 업무의 서비스 방법 B 문
- 방법 A 방법 B는 내부를 호출
이 경우, 프록시 클래스 서비스 'B 방법을 사용하여, 방법 B의 서비스를 호출 처리 방법을 달성하는 것이다 롤백 예외가 발생한다.
통화가 원래 프록시 클래스 서비스 클래스 방식 B의 내부에 사용되는 방법 A는, 그러나 만약 트랜잭션을 구현하지 않는 것은 이상 롤백으로 이어질하지 않습니다.
해결 방법 : 다른 클래스 B 분할 방법은 방법은 프록시 클래스 대신 원래 클래스를 호출 할 보장됩니다.
잘못된 사용
선언적인 트랜잭션 포장 방법은 메소드가 예외를 throw 할 때 롤백,하지만 기본적으로 발생한다 RuntimeException
롤백.
예외가 라이브 먹거나 비를 밖으로 던져 캐치 경우 RuntimeException
, 디폴트는 롤백되지 않습니다.
해결 방법 : 예외를 삼키지 말고, 발생 비 RuntimeException
사용 @Transaction
주석 rollbackFor
매개 변수가 제어됩니다.
다음과 같이 클래스 계층 구조의 java.lang의 일부 Java8는 (기사 참조 하단의 전체 구조를 참조하십시오)입니다 :
java.lang.Object
......
java.lang.Throwable (implements java.io.Serializable)
java.lang.Error
java.lang.AssertionError
java.lang.LinkageError
java.lang.BootstrapMethodError
java.lang.ClassCircularityError
java.lang.ClassFormatError
java.lang.UnsupportedClassVersionError
java.lang.ExceptionInInitializerError
java.lang.IncompatibleClassChangeError
java.lang.AbstractMethodError
java.lang.IllegalAccessError
java.lang.InstantiationError
java.lang.NoSuchFieldError
java.lang.NoSuchMethodError
java.lang.NoClassDefFoundError
java.lang.UnsatisfiedLinkError
java.lang.VerifyError
java.lang.ThreadDeath
java.lang.VirtualMachineError
java.lang.InternalError
java.lang.OutOfMemoryError
java.lang.StackOverflowError
java.lang.UnknownError
java.lang.Exception
java.lang.CloneNotSupportedException
java.lang.InterruptedException
java.lang.ReflectiveOperationException
java.lang.ClassNotFoundException
java.lang.IllegalAccessException
java.lang.InstantiationException
java.lang.NoSuchFieldException
java.lang.NoSuchMethodException
// 这里是RuntimeException
java.lang.RuntimeException
java.lang.ArithmeticException
java.lang.ArrayStoreException
java.lang.ClassCastException
java.lang.EnumConstantNotPresentException
java.lang.IllegalArgumentException
java.lang.IllegalThreadStateException
java.lang.NumberFormatException
java.lang.IllegalMonitorStateException
java.lang.IllegalStateException
java.lang.IndexOutOfBoundsException
java.lang.ArrayIndexOutOfBoundsException
java.lang.StringIndexOutOfBoundsException
java.lang.NegativeArraySizeException
java.lang.NullPointerException
java.lang.SecurityException
java.lang.TypeNotPresentException
java.lang.UnsupportedOperationException
......
复制代码
참고 자료
Yunqi 커뮤니티 - - 같은 선언적인 트랜잭션 메소드 호출 트랜잭션 실패의 봄 알리 구름 (.시는이 원본이 아닌, 내가 정말 원본 텍스트를 찾을 수 없습니다)
java.lang의 클래스 계층 구조 (자바 플랫폼 SE 8)
에서 이동이 문서 내 블로그 를 방문에 오신 것을 환영합니다!