스프링 트랜잭션 롤백
1. 문제 발생
한 가지 방법으로 여러 데이터베이스 저장 작업을 수행할 경우 중간 데이터베이스 작업에서 오류가 발생합니다. 의사 코드는 다음과 같습니다.
public method() { Dao1.save(Person1); Dao1.save(Person2); Dao1.save(Person2);//假如这句发生了错误,前面的两个对象会被保存到数据库中 Dao1.save(Person2); }
예상 상황: 오류가 발생하기 전의 모든 데이터베이스 저장 작업이 롤백됩니다. 즉, 저장이 수행되지 않습니다.
정상 상황: 이전 데이터베이스 작업이 실행되고 데이터베이스 작업이 실행됩니다. 작업 오류가 시작된 후 모든 데이터 저장 작업이 실패합니다. 이는 우리가 원하는 결과가 아니어야 합니다.
이런 상황이 발생하면 Spring 트랜잭션을 사용하여 이 문제를 해결할 수 있습니다.
2. 예외에 대한 기본 지식
1) 예외 아키텍처
예외 상속 구조: Throwable은 기본 클래스이고, Error 및 Exception은 Throwable, RuntimeException 및 IOException을 상속합니다. . 예외를 상속합니다. Error 및 RuntimeException과 그 하위 클래스는 확인되지 않은 예외(unchecked)가 되고, 기타 예외는 확인된 예외(checked)가 됩니다.
2) 오류 예외
오류는 프로그램 실행 중에 매우 심각하고 복구할 수 없는 오류가 발생했음을 나타냅니다. 작업을 중단합니다. 예를 들어 JAVA 가상 머신에 오류가 발생합니다. 오류는 확인되지 않은 예외입니다. 컴파일러는 오류가 처리되었는지 여부를 확인하지 않으며 프로그램에서 오류 유형 예외를 포착할 필요가 없습니다. 일반적인 상황에서는 프로그램에서 Error 유형의 예외가 발생해서는 안 됩니다.
3) RuntimeException
예외에는 RuntimeException 및 기타 RuntimeException이 아닌 예외가 포함됩니다.
RuntimeException은 확인되지 않은 예외입니다. 즉, 컴파일러는 프로그램이 RuntimeException을 처리하는지 여부를 확인하지 않습니다. 프로그램에서 RuntimException 유형의 예외를 포착할 필요가 없으며 RuntimeException 클래스를 선언할 필요도 없습니다. 메소드 본문. RuntimeException이 발생하면 프로그램에 프로그래밍 오류가 발생했다는 의미이므로 RuntimeException을 잡는 대신 오류를 찾아 프로그램을 수정해야 합니다.
4) Checked Exception
프로그래밍에서 가장 많이 사용되는 Exception이기도 한 Checked Exception은 RuntimeException이 아닌 Exception을 상속한 모든 예외를 말합니다. 위 그림의 IOException은 다음과 같습니다. 및 ClassNotFoundException. JAVA 언어는 확인된 예외가 처리되어야 한다고 규정합니다. 컴파일러는 이를 확인하고 메서드 본문에서 확인된 예외를 선언하거나 처리를 위해 확인된 예외를 캡처하기 위해 catch 문을 사용합니다.
3. 예시
여기에 사용된 트랜잭션 구성은 다음과 같습니다.
<!-- Jpa 事务配置 --> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory"/> </bean> <!-- 开启注解事务 --> <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />
스프링 구성 파일에서 데이터 소스의 defaultAutoCommit True 로 설정된 경우 메서드가 자체적으로 예외를 포착하면 트랜잭션이 롤백되지 않습니다. 예외가 자체적으로 포착되지 않으면 다음 예와 같이 트랜잭션이 롤백됩니다.
예를 들어, 구성 파일
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="xxx" value="xxx"/> <property name="xxx" value="xxx"/> .... <property name="defaultAutoCommit" value="true" /> </bean>
에 이러한 기록이 있습니다. 아마도 이 매개변수를 구성하지 않았음을 알게 될 것입니다. 대답은 '아니요'입니다. 저는 com.alibaba를 사용합니다. .druid.pool.DruidDataSource는 데이터베이스 연결 풀입니다. 기본 defaultAutoCommit은 true입니다. 아래 소스 코드를 볼 수 있습니다.
그러면 이제 두 가지 상황이 발생합니다
상황 1:
@Transactional(rollbackOn = { Exception.class }) public void test() throws Exception { doDbStuff1(); doDbStuff2();//假如这个操作数据库的方法会抛出异常,现在方法doDbStuff1()对数据库的操作 会回滚。 }
프로그램에서 수동으로 예외를 포착하지 못한 경우 상황 2:
@Transactional(rollbackOn = { Exception.class }) public void test() { try { doDbStuff1(); doDbStuff2();//假如这个操作数据库的方法会抛出异常,现在方法doDbStuff1()对数据库的操作 不会回滚。 } catch (Exception e) { e.printStackTrace(); } }
프로그램에서 직접 예외를 포착한 경우 이제 필요한 경우는 어떻게 될까요? 예외를 수동으로 포착하고 예외가 발생했을 때 롤백할 수 있기를 원하십니까?
트랜잭션을 수동으로 롤백하려면 다음과 같이 작성하세요.
@Transactional(rollbackOn = { Exception.class }) public void test() { try { doDbStuff1(); doDbStuff2(); } catch (Exception e) { e.printStackTrace(); TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();//就是这一句了,加上之后,如果doDbStuff2()抛了异常, //doDbStuff1()是会回滚的 } }
읽어주셔서 감사합니다! 감사해요!
더 많은 Java Spring 트랜잭션 롤백 관련 기사를 보려면 PHP 중국어 웹사이트를 주목하세요!