Spring MVC + Oracle LOBS + Streaming
سؤال
لا بد لي من إرسال دفق ثنائي من النقطة عن طريق servleTOutputStream.
أنا أستخدم التقنيات والبرامج التالية: Oracle 11 ، WebSphere 7 ، Springframework 2.5.5 ، Hibernate 3.3.Sp1.
هناك قواعد بيانات Oracle. الأول يحتوي على جداول لوصف المستندات التي يجب علي نقلها ، والمحتوى الثاني - محتوى المستندات.
لقد قمت أيضًا بتكوين الدعم لـ XA DataSources في WebSphere و JTatransactionManager في الربيع.
أحصل على إشارة إلى مستند ومحتوى نفسه في معاملة واحدة.
تخبرنا مواصفات JDBC أن LOBs هي كائنات معاملات وأن التطبيقات المحمولة يجب أن تستخدم مثل هذه الكائنات في المعاملات.
ولدي الأسئلة التالية:
- هل من القانوني استرداد دفق الإدخال الخاص بـ 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;
}
إذا لم يكن من القانوني كيفية نقل دفق BLOB الثنائي إلى المستخدم النهائي إذا كان محتوى النقطة كبيرة بما يكفي وهناك مهلة معاملة تم تكوينها مسبقًا في خادم التطبيق؟ هل يجب علي التعامل مع المعاملات يدويًا وتعيين المهلة على الصفر (المعاملة أبدًا
ما هي أفضل طريقة لنقل الدفق الثنائي لـ Blob إلى المستخدم النهائي في مثل هذه الحالة؟
المحلول
أنت على صواب في ذلك العائد ، فإن دفق النقطة من طريقة TX الخاصة بك ليس فكرة جيدة ... قد تعمل في ظل ظروف معينة ، قاعدة البيانات حسب ، لكنها محفوفة بالمخاطر.
الحل هو تحويل المشكلة إلى الخارج. مرر Servlet OutputStream
في طريقة المعاملات الخاصة بك. هذا يتجنب مشكلة المعاملة ، ويبقي معالجة الدفق في مكان واحد:
@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;
}