Pergunta

Eu tenho que enviar um fluxo binário de um blob por meio de um servletOutputStream.

Estou usando as seguintes tecnologias e software: Oracle 11, WebSphere 7, Springframework 2.5.5, Hibernate 3.3.sp1.

Existem dois bancos de dados Oracle. O primeiro contém tabelas para descrição dos documentos que tenho que transferir e o segundo conteúdo dos documentos.

Eu também configurei o suporte para o XA DataSources no WebSphere e JTatransactionManager na primavera.

Obtenho uma referência a um documento e conteúdo em uma transação.

A especificação JDBC nos diz que as lobs são objetos transacionais e aplicativos portáteis devem usar esses objetos nas transações.

E eu tenho as seguintes perguntas:

  1. É legal recuperar o fluxo de entrada da BLOB no método transacional e passá-lo para o método não transacional de nível superior? Algo assim:

    @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. Se não for legal como transferir o fluxo binário do BLOB para o usuário final se o conteúdo do blob for grande o suficiente e houver tempo limite de transação pré -configurado no servidor de aplicativos? Tenho que lidar com transações manualmente e definir o tempo limite para zero (transação nunca mais tempo)?

  2. Qual é a melhor maneira de transferir o fluxo binário do BLOB para o usuário final nesse caso?

Foi útil?

Solução

Você está certo, pois o fluxo do Blob do retorno do seu método TX não é uma boa ideia ... pode funcionar em determinadas circunstâncias, dependendo do banco de dados, mas é arriscado.

A solução é transformar o problema de dentro para fora. Passe o servlet OutputStream no seu método transacional. Isso evita o problema da transação e mantém seu manuseio de fluxos em um só lugar:

@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;
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top