ProgramingTip

롤백으로 만 트랜잭션 : 원인을 어떻게 찾습니까?

bestdevel 2020. 10. 4. 12:02
반응형

롤백으로 만 트랜잭션 : 원인을 어떻게 찾습니까?


내 @Transactional 메서드 내에서 트랜잭션을 커밋하는 데 문제가 있습니다.

methodA() {
    methodB()
}

@Transactional
methodB() {
    ...
    em.persist();
    ...
    em.flush();
    log("OK");
}

methodA ()에서 methodB ()를 호출하면 메소드가 전달되고 로그에 "OK"가 표시됩니다. 하지만 나는

Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Transaction marked as rollbackOnly org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Transaction marked as rollbackOnly
    at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:521)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:393)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:120)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:622)
    at methodA()...
  1. methodB의 예외는 예외에서 제거되어 있습니다.
  2. methodB () 내의 함수가 트랜잭션을 롤백으로 만 표시 했습니까? 어떻게 알 수 있습니까? 예를 들어 다음과 같은 것을 확인하는 방법이 있습니까? getCurrentTransaction().isRollbackOnly()?-이와 같이 방법을 단계별로 수행하고 원인을 수 있습니다.

귀하는 귀하의 방법을 표시하면 @Transactional, 귀하의 방법 내부 예외의 발생은 롤백 전용 (당신이 요구하는 경우에도)로 주변 TX를 표시합니다. @Transactional주석의 다른 속성을 사용 하여 다음과 같은 롤백을 방지 할 수 있습니다 .

@Transactional(rollbackFor=MyException.class, noRollbackFor=MyException2.class)

마침내 문제를 이해했습니다.

methodA() {
    methodB()
}

@Transactional(noRollbackFor = Exception.class)
methodB() {
    ...
    try {
        methodC()
    } catch (...) {...}
    log("OK");
}

@Transactional
methodC() {
    throw new ...();
}

일이 일어나는 무슨 methodB가는에 올바른 주석이 있더라도 methodC오는가 않다는을 구석으로입니다. 예외가 발생하면 두 번째 @Transactional는 첫 번째 트랜잭션을 어쨌든 롤백으로 표시됩니다.


다시 코딩하거나 다시 빌드 할 필요없이 원인 이되는 예외를 가져 오려면 중단 점을

org.hibernate.ejb.TransactionImpl.setRollbackOnly() // Hibernate < 4.3, or
org.hibernate.jpa.internal.TransactionImpl() // as of Hibernate 4.3

스택에서 보통 인터셉터로 올라갑니다. 거기에서 일부 catch 블록에서 발생하는 예외를 읽을 수 있습니다.


내 응용 프로그램을 실행하는 동안 예외로 고생했습니다.

마지막으로 문제는 SQL 쿼리에 비행합니다. 나는 쿼리가 잘못 의미합니다.

쿼리를 확인하십시오. 이 내 제안입니다


...코드 섹션 에서 throw되고 catch되는 예외를 찾습니다 . 런타임 및 롤백 애플리케이션 예외로 인해 다른 장소에서 발견 된 경우에도 비즈니스 메소드에서 폐기 될 때 롤백이 발생합니다.

컨텍스트를 사용하여 트랜잭션이 롤백으로 표시되었는지 여부를 확인할 수 있습니다.

@Resource
private SessionContext context;

context.getRollbackOnly();

Bean.xml에서 transactionmanager를 비활성화하십시오.

<tx:annotation-driven proxy-target-class="true" transaction-manager="transactionManager"/>
    <bean id="transactionManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

이 줄을 주석 처리하면 롤백을 유발하는 예외가 표시됩니다.)


솔루션으로 좋은 설명을 찾았습니다 : https://vcfvct.wordpress.com/2016/12/15/spring-nested-transactional-rollback-only/

1) 실제로 트랜잭션 제어가 필요하지 않은 경우 중첩 된 메서드에서 @Transacional을 제거합니다. 따라서 예외가 있어도 거품이 발생하고 트랜잭션에 영향을 미치지 않습니다.

또는:

2) 중첩 된 메서드에 트랜잭션 제어가 필요한 경우 전파 정책에 대해 REQUIRE_NEW로 설정하여 예외를 throw하고 롤백 전용으로 표시하더라도 호출자에게 영향을주지 않습니다.


productRepository에 아래 코드를 적용하십시오.

@Query("update Product set prodName=:name where prodId=:id ") @Transactional @Modifying int updateMyData(@Param("name")String name, @Param("id") Integer id);

junit 테스트에서 코드 아래에 적용

@Test
public void updateData()
{
  int i=productRepository.updateMyData("Iphone",102);

  System.out.println("successfully updated ... ");
  assertTrue(i!=0);

}

내 코드에서 잘 작동합니다.


@Transactional 가져 오기 를 확인하십시오 .

import javax.transaction.Transactional;

참고 URL : https://stackoverflow.com/questions/19302196/transaction-marked-as-rollback-only-how-do-i-find-the-cause

반응형