die*_*n07 8 java spring hibernate transactions
我试图找出如何最好地结合使用Spring的持久性(以及潜在的其他)异常@Transactional。在这篇文章中,我将仅以一个简单的用户注册示例为例,这可能DataIntegrityViolationException由于用户名重复而引起。
我尝试过以下事情,但对我来说并不令人满意:
val entity = UserEntity(...)
try {
repo.save(entity)
} catch (e: DataIntegrityViolationException) {
// not included: some checks for which constraint failed
throw DuplicateUsername(username) // to be handled by the controller
}
Run Code Online (Sandbox Code Playgroud)
在@Transactional方法中这是行不通的,因为持久性异常只有在提交事务后才会发生,这在spring事务包装器中我的服务方法之外发生。
EntityManager退出前冲洗明确要求flush对EntityManager在我的服务方法结束。这将强制写入数据库,并因此触发异常。但是,它可能是低效的,因为我现在必须注意不要无故在请求期间多次刷新。我也最好永远不要忘记它,否则例外会消失得无影无踪。
将@Transactional方法放在单独的spring bean中,并在主服务中尝试捕获它们。这很奇怪,因为我必须注意将代码的一部分放在A位置,另一部分放在B位置。
DataIntegrityViolationException上控制器就是不行。控制器在处理数据库中的异常方面没有任何业务(色相)。
DataIntegrityViolationException我已经在网上看到了一些资源,尤其是与Hibernate结合使用时,这表明捕获此异常是错误的,应该在保存之前检查条件(即,检查用户名是否存在手动查询)。即使在进行事务处理时,这在并发方案中也不起作用。是的,您将获得交易的一致性,但是DataIntegrityViolationException当“其他人首先出现”时,您仍然会获得一致性。因此,这不是可接受的解决方案。
使用Spring TransactionTemplate代替@Transactional。这是唯一令人满意的解决方案。但是,使用它比“仅仅抛出@Transactional方法”要笨拙得多,甚至Spring文档似乎也会使您偏向使用@Transactional。
我想要一些有关如何最好地处理这种情况的建议。我最后提出的解决方案还有更好的选择吗?
我在我的项目中使用以下方法。
public @interface InterceptExceptions
{
}
Run Code Online (Sandbox Code Playgroud)
<beans ...>
<bean id="exceptionInterceptor" class="com.example.ExceptionInterceptor"/>
<aop:config>
<aop:aspect ref="exceptionInterceptor">
<aop:pointcut id="exception" expression="@annotation(com.example.InterceptExceptions)"/>
<aop:around pointcut-ref="exception" method="catchExceptions"/>
</aop:aspect>
</aop:config>
</beans>
Run Code Online (Sandbox Code Playgroud)
import org.aspectj.lang.ProceedingJoinPoint;
public class ExceptionInterceptor
{
public Object catchExceptions(ProceedingJoinPoint joinPoint)
{
try
{
return joinPoint.proceed();
}
catch (MyException e)
{
// ...
}
}
}
Run Code Online (Sandbox Code Playgroud)
@Service
@Transactional
public class SomeService
{
// ...
@InterceptExceptions
public SomeResponse doSomething(...)
{
// ...
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
611 次 |
| 最近记录: |