Pregunta

Tengo que enviar una corriente binaria de una gota por medio de una ServletOutputStream.

Estoy usando las siguientes tecnologías y software:. Oracle 11, WebSphere 7, Spring Framework 2.5.5, Hibernate 3.3.SP1

Hay dos bases de datos Oracle. El primero contiene las tablas de descripción de documentos que tienen que transferir, y el segundo -. Contenido de los documentos

Me ayuda también han configurado para fuentes de datos XA en WebSphere y JtaTransactionManager en primavera.

I obtener una referencia a un documento y contenido en sí mismo en una transacción.

especificación JDBC nos dice que los LOB son objetos transaccionales y aplicaciones portátiles deben utilizar este tipo de objetos dentro de las transacciones.

Y tengo las siguientes preguntas:

  1. ¿Es legal para recuperar flujo de entrada de BLOB dentro método transaccional y pasarlo al método no transaccional de alto nivel? Algo como esto:

    @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. Si no es legal la forma de transferir secuencia binaria de BLOB al usuario final si el contenido del BLOB es lo suficientemente grande y no hay tiempo de espera de transacción preconfigurado en el servidor de aplicaciones? ¿Tengo que manejar las transacciones manualmente y establecer el tiempo de espera a cero (transacción Nunca el tiempo de espera)?

  2. ¿Cuál es la mejor manera de transferir secuencia binaria de BLOB al usuario final en un caso así?

¿Fue útil?

Solución

Usted no es justo en esa corriente del BLOB regresar está fuera de su método de TX es una buena idea ... que podría funcionar bajo ciertas circunstancias, la base de datos en función, pero es arriesgado.

La solución es convertir el problema de adentro hacia afuera. Pase OutputStream del servlet a su método transaccional. Esto evita el problema de transacción, y mantiene su manejo de flujo en un solo 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 bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top