Spring MVC + Oracle ИДЕТ ТЯЖЕЛО + потоковая передача

Я должен отправить двоичный поток блоба посредством ServletOutputStream.

Я использую следующие технологии и программное обеспечение: Oracle 11, WebSphere 7, Springframework 2.5.5, В спящем режиме 3.3. SP1.

Существует две базы данных Oracle. Первый содержит таблицы для описания документов, которые я должен передать, и второй - содержание документов.

Я также настроил поддержку источников данных XA в WebSphere и JtaTransactionManager пружиной.

Я получаю ссылку на документ и само содержание в одной транзакции.

Спецификация JDBC говорит нам, что СВЕЧИ являются транзакционными объектами, и портативные приложения должны использовать такие объекты в рамках транзакций.

И у меня есть следующие вопросы:

  1. Действительно ли законно получить входной поток BLOB в рамках транзакционного метода и передать его нетранзакционному методу верхнего уровня? Что-то вроде этого:

    @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;
    }
  1. Если не законно, как передать двоичный поток BLOB конечному пользователю, если содержание BLOB является достаточно большим и в сервере приложений существует предварительно сконфигурированный тайм-аут транзакции? Я должен обработать транзакции вручную и обнулить тайм-аут (транзакция никогда не испытывают таймаут)?

  2. Что лучший способ состоит в том, чтобы передать двоичный поток BLOB конечному пользователю в таком случае?

5
задан szhem 15 January 2010 в 07:39
поделиться

1 ответ

Вы правы в том возврате, поток 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;
}
5
ответ дан 14 December 2019 в 19:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: