Aspect Around Transactional 服务抛出 UnexpectedRollbackException
Aspect Around Transactional service throw UnexpectedRollbackException
我在事务服务中有关于方法的方面。
不幸的是,当我通过服务捕获错误时,会抛出另一个异常。我怎样才能防止这个错误?
*我搜索了类似的问题,但似乎没有一个解决方案适合我的情况
@Aspect
@Component
public class ServiceGuard {
@Pointcut("execution(* simgenealogy.service.*.*(..))")
public void persistence() {}
@Around("persistence()")
public Object logPersistence(ProceedingJoinPoint joinPoint) {
try {
Object o = joinPoint.proceed();
return o;
} catch (ConstraintViolationException constraintException) {
// (...)
return null;
} catch (Throwable throwable) {
// (...)
return null;
}
}
}
和错误日志。
2019-07-29 02:10:37.979 ERROR 11300 --- [ion Thread] s.a.g.s.w.ServiceGuard :
Constraint violation: First Name cannot be empty
2019-07-29 02:10:38.023 ERROR 11300 --- [ion Thread] s.a.g.s.w.ServiceGuard :
Constraint violation: Last Name cannot by empty
Exception in thread "JavaFX Application Thread" org.springframework.transaction.UnexpectedRollbackException: Transaction silently rolled back because it has been marked as rollback-only
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:755)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:714)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:534)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:305)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
at
您捕获了可能出于某种原因而发生的异常。然后你只是 return null 作为先前执行的(通过 proceed()
)方法的结果,可能在预期另一个非空 return 值的情况下。
由于您没有提供任何应用程序代码,所以这是推测性的,但我假设空 return 值随后被分配给一个数据 属性,它应该有一个非空值(查看日志中的约束违规)。更准确地说,您将名字和姓氏设置为 null,这会导致违反约束,进而导致您的事务回滚,因为未设置强制数据字段。
如何解决这个问题? first/last 名称的 return 非空默认值(虽然听起来很奇怪)或者让原始异常升级而不是吞下它们并导致后续问题。
底线:您的异常处理刚刚出错,需要修复。
好的,我找到了解决方案。
@Transactional 也是@Arround 切面。问题出在订购方面。我的 Guard class 实际上并不是围绕 Transaction。将@Order(0) 放在Guard 上,将@Order(1) 放在@Transactional 服务上解决了问题。
我在事务服务中有关于方法的方面。 不幸的是,当我通过服务捕获错误时,会抛出另一个异常。我怎样才能防止这个错误? *我搜索了类似的问题,但似乎没有一个解决方案适合我的情况
@Aspect
@Component
public class ServiceGuard {
@Pointcut("execution(* simgenealogy.service.*.*(..))")
public void persistence() {}
@Around("persistence()")
public Object logPersistence(ProceedingJoinPoint joinPoint) {
try {
Object o = joinPoint.proceed();
return o;
} catch (ConstraintViolationException constraintException) {
// (...)
return null;
} catch (Throwable throwable) {
// (...)
return null;
}
}
}
和错误日志。
2019-07-29 02:10:37.979 ERROR 11300 --- [ion Thread] s.a.g.s.w.ServiceGuard :
Constraint violation: First Name cannot be empty
2019-07-29 02:10:38.023 ERROR 11300 --- [ion Thread] s.a.g.s.w.ServiceGuard :
Constraint violation: Last Name cannot by empty
Exception in thread "JavaFX Application Thread" org.springframework.transaction.UnexpectedRollbackException: Transaction silently rolled back because it has been marked as rollback-only
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:755)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:714)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:534)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:305)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
at
您捕获了可能出于某种原因而发生的异常。然后你只是 return null 作为先前执行的(通过 proceed()
)方法的结果,可能在预期另一个非空 return 值的情况下。
由于您没有提供任何应用程序代码,所以这是推测性的,但我假设空 return 值随后被分配给一个数据 属性,它应该有一个非空值(查看日志中的约束违规)。更准确地说,您将名字和姓氏设置为 null,这会导致违反约束,进而导致您的事务回滚,因为未设置强制数据字段。
如何解决这个问题? first/last 名称的 return 非空默认值(虽然听起来很奇怪)或者让原始异常升级而不是吞下它们并导致后续问题。
底线:您的异常处理刚刚出错,需要修复。
好的,我找到了解决方案。 @Transactional 也是@Arround 切面。问题出在订购方面。我的 Guard class 实际上并不是围绕 Transaction。将@Order(0) 放在Guard 上,将@Order(1) 放在@Transactional 服务上解决了问题。