Я должен отправить двоичный поток блоба посредством ServletOutputStream.
Я использую следующие технологии и программное обеспечение: Oracle 11, WebSphere 7, Springframework 2.5.5, В спящем режиме 3.3. SP1.
Существует две базы данных Oracle. Первый содержит таблицы для описания документов, которые я должен передать, и второй - содержание документов.
Я также настроил поддержку источников данных XA в WebSphere и JtaTransactionManager пружиной.
Я получаю ссылку на документ и само содержание в одной транзакции.
Спецификация JDBC говорит нам, что СВЕЧИ являются транзакционными объектами, и портативные приложения должны использовать такие объекты в рамках транзакций.
И у меня есть следующие вопросы:
@Transactional
public InputStream getContent(Long docId) {
Blob blob = getBlob(...);
return blob.getBinaryStream();
}
public ModelAndView handleRequestInternal(HttpServletRequest req, HttpServletResponse resp) {
Long docId = ServlerRequestUtils.getRequiredLongParameter(req);
InputStream is = service.getContent(docId);
copy(is, resp.getOutputStream());
return null;
}
Если не законно, как передать двоичный поток BLOB конечному пользователю, если содержание BLOB является достаточно большим и в сервере приложений существует предварительно сконфигурированный тайм-аут транзакции? Я должен обработать транзакции вручную и обнулить тайм-аут (транзакция никогда не испытывают таймаут)?
Что лучший способ состоит в том, чтобы передать двоичный поток BLOB конечному пользователю в таком случае?
Вы правы в том возврате, поток BLOB из вашего tx метода не является хорошей идеей... это могло бы работать при определенных обстоятельствах, база данных, зависящая, но это опасно.
решение состоит в том, чтобы вывернуть проблему наизнанку. Передать сервлет OutputStream
в к вашему транзакционному методу. Это избегает проблемы транзакции, и сохраняет вашу потоковую обработку в одном месте:
@Transactional
public void getContent(Long docId, OutputStream outputStream) {
Blob blob = getBlob(...);
InputStream blobStream = blob.getBinaryStream();
copy(blobStream, outputStream);
blobStream.close(); // ignoring the usual stream closing try/catch stuff for brevity
}
public ModelAndView handleRequestInternal(HttpServletRequest req, HttpServletResponse resp) {
Long docId = ServlerRequestUtils.getRequiredLongParameter(req);
service.getContent(docId, resp.getOutputStream());
return null;
}