Domanda

Devo inviare un flusso binario di un blob per mezzo di un ServletOutputStream.

Sto usando le seguenti tecnologie e software:. Oracle 11, WebSphere 7, Spring Framework 2.5.5, Hibernate 3.3.SP1

Ci sono due database Oracle. Il primo contiene le tabelle per la descrizione dei documenti devo trasferire, e il secondo -. Contenuto dei documenti

I sostegno inoltre sono configurati per origini dati XA in WebSphere e JtaTransactionManager in primavera.

I ottenere un riferimento a un documento e contenuto stesso in una transazione.

specifica JDBC ci dice che LOB sono oggetti transazionali e applicazioni portatili dovrebbero utilizzare tali oggetti all'interno di transazioni.

E ho le seguenti domande:

  1. E 'legale per recuperare flusso di ingresso di BLOB all'interno del metodo transazionale e passarlo al metodo non transazionale di livello superiore? Qualcosa di simile a questo:

    @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 non è legale come trasferire flusso binario di BLOB per l'utente finale se il contenuto del BLOB è abbastanza grande e non v'è preconfigurato timeout transazione nel server di applicazioni? Devo gestire le transazioni manualmente e impostare il timeout a zero (operazione non timeout)?

  2. Qual è il modo migliore per trasferire flusso binario di BLOB per l'utente finale in un caso del genere?

È stato utile?

Soluzione

Hai ragione in quel flusso di ritorno sta del BLOB dal vostro metodo di tx non è una buona idea ... potrebbe funzionare in determinate circostanze, a seconda del database, ma è rischioso.

La soluzione è quello di trasformare il problema dentro e fuori. Passare OutputStream del servlet al tuo metodo transazionale. Questo evita il problema della transazione, e mantiene il vostro flusso di gestione in un unico luogo:

@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;
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top