2010-01-14 2 views
5

Je dois envoyer un flux binaire d'un objet blob au moyen d'un objet ServletOutputStream. J'utilise les technologies et logiciels suivants: Oracle 11, WebSphere 7, Springframework 2.5.5, Hibernate 3.3.SP1.Spring MVC + Oracle LOBs + Streaming

Il existe deux bases de données Oracle. Le premier contient des tableaux pour la description des documents que je dois transférer, et le second - le contenu des documents.

J'ai également configuré le support pour les sources de données XA dans WebSphere et JtaTransactionManager au printemps.

J'obtiens une référence à un document et contenu lui-même dans une transaction. La spécification JDBC indique que les objets LOB sont des objets transactionnels et que les 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 un délai d'attente de transaction préconfiguré dans le serveur d'application? Dois-je gérer les transactions manuellement et mettre le délai à zéro (transaction jamais expirée)? Quelle est la meilleure façon de transférer le flux binaire de BLOB à l'utilisateur final dans un tel cas?

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

Répondre

5

Vous avez raison dans ce retour est le flux de blob 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 consiste à inverser le problème. Passez le 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; 
} 
+0

Merci beaucoup, je l'ai fait quelque chose de semblable et maintenant je suis inquiet au sujet de délai d'attente de transaction, en particulier lorsque la connexion de l'utilisateur est assez lent et le contenu que je dois transférer est assez grand. Est-il acceptable de définir le délai d'expiration de la transaction sur "transaction never time out"? – szhem

+0

Absolument, pas de problème pour cela – skaffman

+0

Merci encore une fois de votre aide pour trouver une solution acceptable :) – szhem