봄 트랜잭션을 구성 및 사용

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)

에서 이동이 문서 내 블로그 를 방문에 오신 것을 환영합니다!

추천

출처juejin.im/post/5d380bf2e51d454f73356e22