java - developer - بنود خدمة google play




أين ينتمي التعليق التفاعلي @؟ (12)

أضع @Transactional على طبقة @Service وتعيين rollbackFor أي استثناء readOnly لتحسين المعاملة بشكل أكبر.

افتراضيًا ، لن يبحث @Transactional إلا عن RuntimeException (استثناءات لم يتم التحقق منها) ، عن طريق تعيين العودة إلى Exception.class (استثناءات محددة) ، سيتم التراجع عن أي استثناء.

@Transactional(readOnly = false, rollbackFor = Exception.class)

راجع التحقق مقابل الاستثناءات التي لم يتم التحقق منها .

يجب وضع @Transactional في فئات DAO و / أو أساليب الخاصة بهم أو هل الأفضل توضيحية فئات الخدمة التي يتم استدعاء باستخدام كائنات DAO؟ أو هل من المنطقي أن تشرح "الطبقات"؟


أعتقد أن المعاملات تنتمي إلى طبقة الخدمة. إنه الشخص الذي يعرف عن وحدات العمل وحالات الاستخدام. إنها الإجابة الصحيحة إذا كان لديك العديد من DAOs المحقونة في الخدمة التي تحتاج إلى العمل معًا في معاملة واحدة.


أولا وقبل كل شيء دعونا تحديد حيث يتعين علينا استخدام المعاملات ؟

أﻋﺗﻘد أن اﻹﺟﺎﺑﺔ اﻟﺻﺣﯾﺣﺔ ھﻲ - ﻋﻧدﻣﺎ ﻧﺣن ﺑﺣﺎﺟﺔ إﻟﯽ اﻟﺗﺄﮐد ﻣن أن ﺳﻟﺳﻟﺔ اﻷﻋﻣﺎل ﺳﯾﺗم اﻻﻧﺗﮭﺎء ﻣﻌﮭﺎ ﮐﻌﻣﻟﯾﺔ ﻧووﯾﺔ أو ﻟن ﯾﺗم إﺟراء أي ﺗﻐﯾﯾرات ﺣﺗﯽ ﻓﻲ ﺣﺎﻟﺔ ﻓﺷل أﺣد اﻹﺟراءات.

من الممارسات الشائعة وضع منطق الأعمال في الخدمات. لذلك قد تحتوي طرق الخدمة على إجراءات مختلفة يجب إجراؤها كوحدة منطقية واحدة للعمل. إذا كان الأمر كذلك - فيجب وضع علامة على هذه الطريقة كسلسلة معاملات . بالطبع ، لا تتطلب كل طريقة هذا القيد ، لذلك لا تحتاج إلى وضع علامة على الخدمة الكاملة كمعاملة .

وأكثر من ذلك - لا تنس أن تأخذ في الاعتبار أن Transactional من الواضح ، قد يقلل من أداء الطريقة. من أجل رؤية الصورة كاملة يجب أن تعرف مستويات عزل المعاملة. قد يساعدك معرفة ذلك في تجنب استخدام Transactional حيث لا يلزم بالضرورة.


الإجابة الصحيحة لأبنية الربيع التقليدية هي وضع دلالات المعاملات في فئات الخدمة ، للأسباب التي وصفها الآخرون بالفعل.

الاتجاه الناشئ في الربيع هو نحو التصميم المدفوع بالمجال (DDD). ربيع رو يجسد الاتجاه بشكل جيد. والفكرة هي جعل كائن المجال POJOs richer بكثير مما هو عليه في معماريات الربيع النموذجية (عادة ما تكون anemic ) ، وعلى وجه الخصوص لوضع المعاملات ودلالات الثبات على كائنات المجال نفسها. في الحالات التي يكون فيها كل ما تحتاج إليه هو عمليات CRUD بسيطة ، تعمل وحدات تحكم الويب مباشرة على كائن المجال POJOs (تعمل ككيانات في هذا السياق) ، ولا يوجد مستوى خدمة. في الحالات التي يكون فيها نوع من التنسيق مطلوبًا بين كائنات المجال ، يمكنك الحصول على مقبض وحدة خدمة ، مع @Transaction حسب التقليد. يمكنك تعيين انتشار المعاملة على كائنات المجال إلى شيء مثل REQUIRED بحيث تستخدم كائنات المجال أية معاملات موجودة ، مثل المعاملات التي تم تشغيلها في وحدة خدمة الخدمة.

تقنيًا ، تستخدم هذه التقنية AspectJ و <context:spring-configured /> . تستخدم Roo تعاريف AspectJ inter-type لفصل دلالات الكيان (المعاملات والمثابرة) من عناصر كائن المجال (أساسًا الحقول وأساليب العمل).


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

لنفترض أننا نضيفه إلى DAO ومن الخدمة التي نطلق عليها فئتين DAO ، فشل واحد ونجاح آخر ، في هذه الحالة إذا كان @Transactional ليس على الخدمة سوف يرتكب DB واحد @Transactional .

ومن ثم فإن توصيتي هي استخدام هذا التعليق التوضيحي بحكمة واستخدامه في طبقة الخدمة فقط.

مشروع جيثوب- جافا-ألغوس


ستكون الحالة العادية هي التعليق على مستوى طبقة الخدمة ، ولكن هذا يعتمد حقاً على متطلباتك.

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

ملاحظة: سيحافظ التعليق على DAOs المعاملات قصيرة قدر الإمكان ، مع العائق الذي تعطل وظيفة طبقة الخدمة الخاصة بك في معاملة واحدة (rollbackable).

ليس من المنطقي وضع تعليقات على كلا الطبقتين إذا تم تعيين وضع الانتشار على الوضع الافتراضي.



للمعاملات في مستوى قاعدة البيانات

في الغالب كنت تستخدم @Transactional في DAO فقط على مستوى الأسلوب ، لذلك يمكن أن يكون التكوين خصيصا لطريقة / استخدام الافتراضي (مطلوب)

  1. طريقة DAO التي تحصل على جلب البيانات (حدد ..) - لا تحتاج إلى @Transactional يمكن أن يؤدي هذا إلى بعض النفقات @Transactional بسبب معاملات المعامِلات / و وكيل AOP الذي يجب أن يتم تنفيذه كذلك.

  2. أساليب DAO التي تقوم بإدراج / تحديث ستحصل على @Transactional

بلوق جيدة للغاية على transctional

لمستوى التطبيق -
أنا أستخدم معاملات لمنطق الأعمال وأود أن أكون قادرًا على التراجع في حالة حدوث خطأ غير متوقع

@Transactional(rollbackFor={MyApplicationException.class})
public void myMethod(){

    try {    
        //service logic here     
    } catch(Throwable e) {

        log.error(e)
        throw new MyApplicationException(..);
    }
}

من الناحية المثالية ، طبقة الخدمة (المدير) تمثل منطق عملك ومن ثم يجب أن يتم @Transactional باستخدام @Transactional قد تستدعي طبقة الخدمة المختلفة DAO لتنفيذ عمليات DB. دعونا نفترض الحالات حيث لديك عدد N من عمليات DAO في أسلوب خدمة. إذا فشلت عملية DAO 1 الخاصة بك ، قد لا يزال يتم تمرير الآخرين وسوف ينتهي في حالة غير متناسقة DB. يمكن أن توفر طبقة خدمة التعليق من مثل هذه الحالات.


يجب وضع @Transactional التعليقات التوضيحية حول جميع العمليات التي لا يمكن فصلها. باستخدام @Transactional معاملة @Transactional يتم التعامل معها تلقائيًا.في هذه الحالة إذا تم استدعاء طريقة أخرى بالطريقة الحالية ، فإن هذه الطريقة سيكون لها خيار الانضمام إلى المعاملة الجارية.

لذا لنأخذ المثال:

لدينا نموذج 2 أي Country City . تشبه عملية وضع خريطة نمطية Country City نموذجًا واحدًا يمكن أن يكون Country عدّة مدن.

@OneToMany(fetch = FetchType.LAZY, mappedBy="country")
private Set<City> cities;

هنا Lazily البلد مع مدن متعددة Lazily . هنا يأتي دور @Transactinal عندما نقوم باسترداد كائن البلد من قاعدة البيانات ، ثم نحصل على جميع البيانات من كائن البلد ولكن لن تحصل على مجموعة من المدن لأننا جلب المدن LAZILY .

//Without @Transactional
public Country getCountry(){
   Country country = countryRepository.getCountry();
   //After getting Country Object connection between countryRepository and database is Closed 
}

عندما نريد الوصول إلى Set of Cities من كائن country ، فسوف نحصل على قيم null في تلك المجموعة لأن كائن Set الذي تم إنشاؤه فقط هذه المجموعة لا يتم تهيئته مع وجود بيانات للحصول على قيم Set نستخدم @Transactional أي ،

//with @Transactional
@Transactional
public Country getCountry(){
   Country country = countryRepository.getCountry();
   //below when we initialize cities using object country so that directly communicate with database and retrieve all cities from database this happens just because of @Transactinal
   Object object = country.getCities().size();   
}

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


يجب استخدام @Transactional على طبقة الخدمة لأنها تحتوي على منطق الأعمال. عادةً ما تحتوي طبقة DAO على عمليات CRUD لقاعدة البيانات فقط.

// the service class that we want to make transactional
@Transactional
public class DefaultFooService implements FooService {

    Foo getFoo(String fooName);

    Foo getFoo(String fooName, String barName);

    void insertFoo(Foo foo);

    void updateFoo(Foo foo);
}

مستند الربيع: https://docs.spring.io/spring/docs/4.2.x/spring-framework-reference/html/transaction.html


@Transactional الاستخدامات التي يتم استخدامها في طبقة الخدمة التي يتم استدعاؤها باستخدام طبقة جهاز التحكم ( @Controller ) ودعوة طبقة الخدمة إلى طبقة DAO ( @Repository ) ، أي عملية قاعدة البيانات ذات الصلة.







dao