Frage

Ich habe einen binären Strom eines Blobs mit Hilfe eines ServletOutputStream zu senden.

Ich verwende die folgenden Technologien und Software. Oracle 11, WebSphere 7, spring 2.5.5, Hibernate 3.3.SP1

Es gibt zwei Oracle-Datenbanken. Die erste enthält Tabellen zur Beschreibung von Dokumenten, die ich zu übertragen haben, und die zweite -. Inhalt der Dokumente

Ich habe auch so konfiguriert Unterstützung für XA-Datenquellen in WebSphere und JtaTransactionManager im Frühjahr.

erhalte ich einen Verweis auf ein Dokument und Inhalt selbst in einer einzigen Transaktion.

JDBC-Spezifikation sagt uns, dass LOB sind Transaktionsobjekte und portable Anwendungen sollten solche Objekte innerhalb von Transaktionen verwenden.

Und ich habe folgende Fragen:

  1. Ist es legal BLOB des Eingangsstroms innerhalb Transaktionsverfahren abzurufen und auf der obersten Ebene nicht transaktionale Methode übergeben? So etwas wie folgt aus:

    @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. Wenn es nicht legal ist, wie BLOB des binären Strom an den Endverbraucher zu übertragen, wenn der Inhalt des BLOB groß genug ist, und es ist so vorkonfiguriert Transaktion Timeout in dem Anwendungsserver? Muss ich auf Transaktionen verarbeiten manuell und stellen Sie den Timeout auf Null (Transaktion nie Timeout)?

  2. Was ist der beste Weg, um binäre Stream des Transfer BLOB an den Endverbraucher in einem solchen Fall?

War es hilfreich?

Lösung

Du hast Recht, dass der Strom des Blobs Rückkehr aus Ihrem tx-Methode ist keine gute Idee ... es könnte unter bestimmten Umständen arbeiten, Datenbank abhängig, aber es ist riskant.

Die Lösung ist das Problem von innen nach außen zu drehen. Übergeben Sie die OutputStream des Servlets in Ihrem Transaktionsmethode. Dies vermeidet die Transaktion Ausgabe, und hält Ihren Stream Handling an einem Ort:

@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;
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top