【发布时间】:2018-04-28 15:33:48
【问题描述】:
我有一些二进制数据存储在 Postgres 的 Blob 中。我通过 JPA 使用数据库,但在这种情况下这并不重要。我有一个 spring MVC @Controller 应该能够通过端点提供这些数据。我想流式传输数据,因为为什么要将它全部加载到内存中。大致如下:
@Entity
class MyEntity {
@Lob
Blob data;
}
@RequestMapping(...)
public InputStreamResource getResource(...) {
return new InputStreamResource(myEntityRepository.findById(id).getData().getBinaryStream());
}
不幸的是,这给了我:
java.io.IOException:org.postgresql.util.PSQLException:错误:无效 大对象描述符:1
我知道为什么:当您使用 Blob 时,您需要 run in transaction。现在我已经尝试过:
注释整个控制器方法
@Transactional- 没有帮助,因为当 Spring 开始将流复制到 servlet 响应中时,它已经在事务方面之外。 :'(我还验证了如果我在控制器内部将输入流复制到
byte[]中,一切正常。但这不是流媒体。
byte[] data = IOUtils.toByteArray(myEntityRepository.findById(id).getData().getBinaryStream());
return new ByteArrayResource(data);
很明显,@Transactional 方面的问题是更接近控制器方法,即获取返回值并将其转换为 servlet 响应的方法。
有没有办法重新排序这些方面?还有其他解决方案吗?
谢谢!
编辑:
似乎它应该只需通过 @EnableTransactionManagement(order = Ordered.HIGHEST_PRECEDENCE) 就可以工作,不幸的是事实并非如此。可能是因为@EnableAspectJAutoProxy(proxyTargetClass = true)?
编辑2:
这显然是一个更普遍的问题。 @RequestMapping 注释方法只返回 Stream 但只有在调用完成后 - 包括所有方面和 @Transactional - 返回的值(流)被进一步处理。所以事实上,我希望将事务扩展到实际调用控制器方法的类,可能是整个Servlet.doXXX 方法。没有好消息。
【问题讨论】:
-
春季版?
-
弹簧启动 1.5
-
是否可以在 Spring Boot 2.0 中的
Spring Webflux中迁移?
标签: java spring-mvc streaming blob