为什么我得到一个SpringFramework UnexpectedRollbackException?

问题描述 投票:2回答:1

我收到以下Spring Framework错误消息:

Invocation of getLogoForGlobalConext() in class $Proxy44 threw exception
org.springframework.transaction.UnexpectedRollbackException:
Transaction rolled back because it has been marked as rollback-only
at template/includes/macros.vm line 1651, column 43

我打开macros.vm并查找了1651行,它看起来像这样:

#set ($globalLogo = $spaceManager.getLogoForGlobalContext());

根据我的研究,它看起来像$Proxy44实际上是$spaceManager变量(或DefaultSpaceManager.java的一个实例)。

当Web应用程序尝试下载位于Web服务器/数据库某处的图像/附件时,此消息随机出现。

附件管理器由Spring的事务管理控制,下载图像/附件时使用以下事务属性:

  1. 传播 - 用于附件管理器中的所有方法
  2. 传播和只读 - 用于以“get”开头的附件管理器中的所有方法。

属性在Spring Framework - Chapter 9. Transaction management中定义。我在想的是我需要在事务上设置超时(比如将其设置为无穷大)。

spring transactions confluence
1个回答
2
投票

事实证明,其中一个getter方法正在执行对数据库的写入。具体来说,它每隔几分钟用一些信息更新缓存。发生此更新时,UnexpectedRollbackException被抛出。由于此事务应该是由上述事务属性定义的“只读”,因此我们不允许在getter操作期间执行更新。

我更改了getter方法,不对缓存执行任何更新,即使过期也只是使用缓存,并且错误消失了。

希望这有助于其他人。

© www.soinside.com 2019 - 2024. All rights reserved.