5

ServletOutputStream を使用してブロブのバイナリ ストリームを送信する必要があります。

次のテクノロジとソフトウェアを使用しています: Oracle 11、WebSphere 7、Springframework 2.5.5、Hibernate 3.3.SP1。

2 つの Oracle データベースがあります。1 つ目は転送する必要があるドキュメントの説明の表で、2 つ目はドキュメントの内容です。

春には、WebSphere と JtaTransactionManager で XA データソースのサポートも構成しました。

ドキュメントへの参照とコンテンツ自体を 1 回のトランザクションで取得します。

JDBC 仕様は、LOB はトランザクション オブジェクトであり、移植可能なアプリケーションはトランザクション内でそのようなオブジェクトを使用する必要があることを示しています。

そして、私は次の質問があります:

  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 のバイナリ ストリームをエンド ユーザーに転送する最善の方法は何ですか?

4

1 に答える 1

5

txメソッドからBLOBのストリームを返すのは良い考えではありません...データベースによっては特定の状況下で機能する可能性がありますが、リスクがあります。

解決策は、問題を裏返しにすることです。サーブレットOutputStreamをトランザクションメソッドに渡します。これにより、トランザクションの問題が回避され、ストリームの処理が1か所に保持されます。

@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;
}
于 2010-01-14T17:43:42.150 に答える