سؤال

لدي وحدة جلسات عديمة الحالة تحتوي على طريقة عامة واحدة والعديد من الطرق الخاصة وبعض متغيرات مستوى المثيل.يوجد أدناه مثال على الكود الزائف.

private int instanceLevelVar

public void methodA(int x) { 
  this.instanceLevelVar = x;
  methodB();
}

private void methodB() {
  System.out.println(instanceLevelVar);
}

ما أراه هو أن الطريقة B تقوم بطباعة القيم التي لم يتم تمريرها إلى الطريقة A.أفضل ما يمكنني قوله هو أن قيم الطباعة من مثيلات أخرى لنفس الحبة.ما الذي يسبب هذا؟

يجب أن أشير إلى أن الكود يعمل كما هو متوقع بنسبة 99.9٪ من الوقت.ومع ذلك، فإن .01% يسبب بعض المشكلات/المخاوف الخطيرة بالنسبة لي.

أدرك أنه إذا كانت لدي طرق عامة مختلفة، فقد لا أتمكن من استعادة نفس الفول بين المكالمات، مما قد يؤدي إلى هذا السلوك.ومع ذلك، في هذه الحالة يكون الاستدعاء الوحيد هو الأسلوب العام الوحيد.هل ستستمر الحاوية (السمكة الزجاجية في هذه الحالة) في تبديل الحبوب بين استدعاءات الطريقة الخاصة؟

(تحرير) قمت بإعادة تسمية "مستوى الفئة" إلى "مستوى المثيل" لأن هذا كان يسبب بعض الارتباك.

هل كانت مفيدة؟

المحلول

وأود فقط لا تهتم باستخدام متغير مثيل في الفول جلسة عديمي الجنسية على الإطلاق. بغض النظر عن ما سبب المشكلة التي واجهت، هو على الأرجح لا شيء كنت تريد أن تفعل أي حال. فقط حاول استخدام المتغيرات المحلية في جميع أنحاء أو تحديد المتغيرات المثال في مساعد الطبقات كنت تتصل من الدورة عديمي الجنسية الأساليب التجارية الفول.

نصائح أخرى

وعندما قرأت ما هو فول الدورة؟ قسم من البرنامج التعليمي J2EE 1.4:

<اقتباس فقرة>   

فاصوليا الدورة عديمي الجنسية

     

A <م> جلسة البدون الفول لا الحفاظ على حالة حوارية لعميل معين. عند استدعاء عميل طريقة حبة عديمي الجنسية، قد تحتوي على متغيرات المثال الفول في الدولة، ولكن فقط لمدة الاحتجاج. عند الانتهاء من طريقة، لم يعد الإبقاء على الدولة. إلا أثناء استدعاء الأسلوب، كافة مثيلات حبة عديمي الجنسية وتعادل، والسماح للحاويات EJB لتعيين مثيل إلى أي عميل.

في قضيتك، والدعوة إلى methodB() من methodA() يكون على نفس المثال وما يعادل this.methodB(). أنا بالتالي تميل إلى القول بأن methodB() يمكن لشيء لا إخراج آخر أن القيمة التي ما تم تمريرها إلى methodA().

وهذا ما تؤكده الجملة الأولى في القسم 7.11.8 في في EJB 2.0 المواصفات : <م>". الحاوية يجب التأكد من أن مؤشر واحد فقط يمكن المنفذة مثيل في أي وقت " هذا يعني أنك لا يمكن أن تأتي إلى الحالة التي تكون فيها وسوف تكون مختلطة البيانات (المتغيرات مثيل) من مختلف العملاء (موضوع). كنت ضمان وصول فريدة من نوعها لمتغيرات المثال حتى عاد methodA()!

وقال ذلك، انا لا اقول ان لم يكن لديك مشكلة في مكان ما. لكنني لا أعتقد أن رمز زائف الخاص بك هو ما يعادلها.

و(تحرير:.. بعد قراءة بعض التعليقات على سؤال OP، وهناك الآن بوضوح أدنى شك حول رمز الزائفة والدلالي المستخدمة أنا توضيح العواقب المحتملة أدناه)

وكما أكد جراح الصواريخ، ماذا تقصد بالضبط من قبل الطبقة متغير ؟ هل تعني حقا <م> الطبقة متغير بدلا من المثال متغير ؟ إذا كان الجواب نعم، لا يعكس رمز زائف ذلك، ولكن هذا سوف تؤدي بوضوح إلى سلوك غير متوقع. في الواقع، من قسم 24.1.2 (والنقطة الأولى) في المواصفات EJB 2.0، فمن الواضح أنه لا يسمح لك لإرسال البيانات إلى متغير فئة (على الرغم من أنك يمكن أن تفعل ذلك). يجب أن يكون هناك سبب وجيه لذلك:)

والسبب المرجح لهذه القضية هو أن الحاوية يستخدم نفس الكائن في طلبين (لذلك خيطين) في نفس الوقت. لذلك الترابط الأول يحصل على السطر الذي يستدعي methodB ثم موضوع القادم يحصل على رمز الذي يدعو methodB ثم مؤشر ترابط الأول ينفذ الدعوة إلى methodB، تسبب المشكلة. وهذا يفسر السلوك، على أية حال. لا يبدو لتتناسب مع المواصفات، ولكن يمكن أن يكون مجرد خلل.

في عام، حتى إذا كان مسموحا به، والحفاظ على الدولة في الفول ليست فكرة عظيمة. أنه يؤدي إلى رمز الارتباك، ويمكن أن يؤدي بسهولة إلى البق حيث كنت قد نسيت أن تبدأ من جديد مع كل ما تبذلونه من ولايتك على كل استدعاء الأسلوب.

وسيكون أفضل بكثير لمجرد تمرير هذه الكائنات حولها بين الأساليب، والتي من شأنها أن تجنب كل القضايا.

ربما لا تقوم بإعادة تهيئة متغير المثيل بشكل صحيح.

متغيرات سريعة

بشكل عام، لا ينبغي لنا أن نحتفظ بالحالة في جلسة العمل عديمة الحالة.الكائنات المشار إليها بواسطة متغيرات الحالة، إذا لم يتم إلغاؤها بعد استخدامها، فإنها تظل حية حتى نهاية الطلب وحتى لفترة أطول إذا قامت حاوية EJB الخاصة بنا بتجميع حبوب الجلسة لإعادة استخدامها.في الحالة الأخيرة، نحتاج إلى التأكد من إعادة تهيئة متغير المثيل بشكل صحيح أثناء الطلب اللاحق.ولذلك فإن استخدام متغيرات الحالة قد يؤدي إلى المشكلات التالية:

  • أثناء نفس الطلب، يمكن لمتغير المثيل المشترك بين طرق مختلفة أن يؤدي بسهولة إلى أخطاء حيث يمكننا ننسى أن نبدأ من جديد بالحالة الصحيحة في كل استدعاء للأسلوب
  • في حالة قيام حاوية EJB بتجميع حبوب الجلسة وقد يفشل الكود الخاص بنا في إعادة تهيئة متغيرات المثيل بشكل صحيح، فقد نقوم بذلك إعادة استخدام الحالة القديمة المحددة في طلب سابق
  • متغيرات المثيل لديها نطاق المثيل مما قد يؤدي إلى مشاكل تسرب الذاكرة حيث يتم استخدام المساحة الموجودة في الكومة للاحتفاظ بالكائنات التي لم تعد (أو لا ينبغي استخدامها) تستخدم بعد الآن.

متغيرات الطبقة

أما بالنسبة لمتغيرات المثال، فلا ينبغي استخدام متغيرات الفئة للحفاظ على الحالة المشتركة في حبة الجلسة عديمة الحالة.هذا لا يعني أننا يجب ألا نستخدم الكلمة الأساسية الثابتة ولكن يجب أن نستخدمها بحذر (على سبيل المثال:تحديد الثوابت غير القابلة للتغيير، وبعض فئات المصنع الثابتة، وما إلى ذلك)

ولأن هذا أمر غريب جدًا، فقد أجريت اختبارًا سريعًا باستخدام Netbeans وGlassfish 2.1 المحلي.

  1. قم بإنشاء مشروع جديد باستخدام Samples->Java EE->Servlet Stateless.يؤدي هذا إلى إنشاء مشروع مؤسسي باستخدام حبة بسيطة عديمة الحالة وبرنامج servlet يستخدمها.
  2. لقد قمت بتعديل الحبة عديمة الجنسية لتبدو بهذا الشكل، وأقرب ما يمكن إلى المثال الخاص بك على ما أعتقد.

    @Stateless
    public class StatelessSessionBean implements StatelessSession {
    
       String clName;
    
       private void testNa() {
          System.out.println(clName);
       }
    
       public String sayHello(String name) {
          this.clName = name;
          testNa();
          return "Testcase";
       }
    }
    

وهذا يعمل كما ينبغي.لا أعرف ما هو المحرر الذي تستخدمه، ولكن إذا كان Netbeans فقد يكون من المثير للاهتمام تشغيله بنفسك.

كل هذا يتوقف على ما تعنيه بـ "متغير مستوى الفصل".يجب أن يحتوي متغير الفئة على المعدل الثابت.لو clName لا، ثم كل مثال تحتوي حبة الجلسة عديمة الجنسية على نسختها الخاصة من clName.من المحتمل أن يكون خادم Java EE الخاص بك قد أنشأ مجموعة مكونة من مثيلين أو أكثر من وحدات الجلسة عديمة الحالة، وكل من استدعاءاتك إلى testNa() و sayHello() يتم إرسالها إلى مثيل تعسفي.

وأنا تعثرت على هذا السؤال عندما كنت تعاني من نفس المشكلة. في حالتي، وطريقة الخاص يحدد في الواقع المتغير المثال. ما لاحظته هو أنه في بعض الأحيان المتغير سبيل المثال تم تعيين بالفعل، ومن الواضح أن من طلب سابق.

@Stateless
public class MyBean {
  String someString;

  public void doSomething() {
    internalDoSomething();
  }

  private void internalDoSomething() {
    if (someString != null) {
      System.out.println("oops, someString already contained old data");
    }

    this.someString = "foo";
  }
}

وأنا أعتقد أنه من المنطقي. عندما يستخدم إعادة الحاوية مثيل التخزين المؤقت، وكيف ينبغي عليها أن تعرف كيفية مسح المتغيرات ...

للي، وهذا ما يتماشى مع ويؤكد كل من إشارة باسكال لالمواصفات EJB ( "معتمدة المتغيرات مثلا") والتوصية صاروخ الجراح ( "لا تفعل ذلك، استخدم المتغيرات المحلية بدلا من ذلك").

والمشكلة مع استخدام المتغيرات مثيل في الفول عديمي الجنسية.

وفقا لمواصفات JEE نفس المثال EJB عديمي الجنسية قد تكون مشتركة مع عميل آخر أيضا. حكم الإبهام ليس لخلق المتغيرات المثال في عديمي الجنسية لل EJBs.

قد يكون من الممكن يتم توفير اثنين من عملاء الوصول إلى التطبيق في وقت واحد سبيل المثال EJB نفسه الذي من شأنه أن يخلق مشاكل لأنه ليس هناك عدم تناسق البيانات.

لذلك ليست فكرة جيدة لاستخدام المتغيرات مثلا في الفول EJB عديمي الجنسية.

وكان لي مشكلة مماثلة لأنني استخدمت متغير فئة ثابتة العالمي في صفي المنظمة بتبني وعندما أتيحت لي المتزامنة عديمي الجنسية EJB على التوالي، والكتابة متغير من حالات أخرى.

ويجري تقاسم حقول فئة ثابتة بين كافة مثيلات فئة معينة، ولكن فقط في إطار واحد آلة جافا الافتراضية (JVM). تحديث حقل الدرجة ثابت يعني وجود نية لتقاسم قيمة الحقل بين جميع مثيلات الفئة.

والأمل مساعدة شخص آخر:)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top