Question

Je dois envoyer un flux binaire d'un blob au moyen d'un ServletOutputStream.

J'utilise les technologies et les logiciels suivants:. Oracle 11, WebSphere 7, Springframework 2.5.5, Hibernate 3.3.SP1

Il existe deux bases de données Oracle. La première contient des tableaux pour la description des documents que je dois transférer, et le second -. Contenu des documents

I support ont également configuré pour XA dans les sources de données et WebSphere JtaTransactionManager au printemps.

J'obtiens une référence à lui-même un document et le contenu en une seule transaction.

spécification JDBC nous dit que LOB sont des objets transactionnels et applications portables doivent utiliser ces objets dans les transactions.

Et j'ai les questions suivantes:

  1. Est-il légal pour récupérer le flux d'entrée de blob au sein de méthode transactionnelle et le transmettre à la méthode non transactionnel de haut niveau? Quelque chose comme ceci:

    @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. S'il est pas légal comment transférer flux binaire de blob à l'utilisateur final si le contenu de blob est assez grand et il y a délai d'attente de transaction préconfiguré dans le serveur d'application? Dois-je gérer manuellement les transactions et définir le délai à zéro (transaction chronométrer jamais out)?

  2. Quelle est la meilleure façon de transférer flux binaire de blob à l'utilisateur final dans un tel cas?

Était-ce utile?

La solution

Vous avez raison que le retour se blob de flux de votre méthode tx est pas une bonne idée ... il pourrait fonctionner dans certaines circonstances, la base de données en fonction, mais il est risqué.

La solution est de transformer le problème intérieur. Passez la OutputStream du servlet à votre méthode transactionnelle. Cela permet d'éviter le problème de la transaction, et maintient votre traitement de flux en un seul endroit:

@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;
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top