আমি কোথায় ট্রানজেকশনের টীকায়িত করব: একটি ইন্টারফেস সংজ্ঞা বা একটি বাস্তবায়নকারী ক্লাসে?


91

কোডে শিরোনাম থেকে প্রশ্ন:

@Transactional (readonly = true)
public interface FooService {
   void doSmth ();
}


public class FooServiceImpl implements FooService {
   ...
}

বনাম

public interface FooService {
   void doSmth ();
}

@Transactional (readonly = true)
public class FooServiceImpl implements FooService {
   ...
}

উত্তর:


121

Http://static.springsource.org/spring/docs/2.0.x/references/transaction.html থেকে

স্প্রিং দলের সুপারিশটি হ'ল আপনি কেবল টীকা সহ কংক্রিটের ক্লাসগুলি @Transactionalটীকাগুলি বর্ণিত ইন্টারফেসগুলির বিপরীতে ot আপনি অবশ্যই @Transactionalএকটি ইন্টারফেসের (বা একটি ইন্টারফেস পদ্ধতি) এ টীকা রাখতে পারেন , তবে এটি কেবলমাত্র তখনই কাজ করবে যদি আপনি ইন্টারফেস-ভিত্তিক প্রক্সিগুলি ব্যবহার করে থাকেন তবে আপনি এটির মতো প্রত্যাশা করবেন। টীকাগুলি উত্তরাধিকার সূত্রে প্রাপ্ত নয় এর অর্থ হ'ল আপনি যদি শ্রেণিভিত্তিক প্রক্সি ব্যবহার করছেন তবে লেনদেনের সেটিংসটি শ্রেণিভিত্তিক প্রক্সিং অবকাঠামো দ্বারা স্বীকৃত হবে না এবং অবজেক্টটি কোনও লেনদেনের প্রক্সিতে আবৃত হবে না (যা সিদ্ধান্তগতভাবে খারাপ হবে ) । সুতরাং দয়া করে স্প্রিং টিমের পরামর্শ নিন এবং টীকা সহ কেবল কংক্রিটের ক্লাসগুলি (এবং কংক্রিটের ক্লাসগুলির পদ্ধতিগুলি) @Transactionalএন্টারোটেট করুন।

দ্রষ্টব্য: যেহেতু এই প্রক্রিয়া প্রক্সি ভিত্তিক, কেবলমাত্র প্রক্সি মাধ্যমে আসা 'বাহ্যিক' পদ্ধতি কলগুলি বাধা দেওয়া হবে। এর অর্থ হ'ল 'স্ব-আহ্বান', অর্থাত্ টার্গেট অবজেক্টের মধ্যে এমন একটি পদ্ধতি যা টার্গেট অবজেক্টের অন্য কোনও পদ্ধতিকে কল করে, রানটাইমে প্রকৃত লেনদেনের দিকে পরিচালিত করে না, এমনকি যদি অনুরোধ করা পদ্ধতিটি চিহ্নিত করা হয় @Transactional!

(প্রথম বাক্যে জোর দেওয়া, মূল থেকে অন্য জোর।


বড় +1 বিটিডাব্লু, আমি উদ্ধৃতিটি উদ্ধৃতি দেওয়ার স্বাধীনতা নিয়েছি, যাতে লোকেরা বিভ্রান্ত হয় না, এবং মূলটি থেকে ইতরগুলি এবং এগুলি আবার যুক্ত করে।
টিজে ক্রাউডার

আমি স্প্রিং ডকুমেন্টে এই বিবৃতিটি আগেও পড়েছি, তবে এখনও বুঝতে পারি না কেন শ্রেণিভিত্তিক প্রক্সিং অবকাঠামোগত লেনদেন সেটিংস স্বীকৃতি পাবে না ? আমি ব্যক্তিগতভাবে মনে করি, এটি কেবল বসন্ত বাস্তবায়ন সীমাবদ্ধতা, অন্তর্নিহিত প্রক্সি অবকাঠামোগত সমস্যা নয়।
dma_k

বসন্তের উত্সগুলির JdkDynamicAopProxyদিকে নজর দেওয়া একজন খুঁজে বার করতে পারেন যা প্রতিটি পদ্ধতিতে বিন বিন্যাসের সমস্ত বিন পরামর্শদাতাদের মধ্য দিয়ে যায় (এটিও দেখুন DefaultAdvisorChainFactory#getInterceptorsAndDynamicInterceptionAdvice()), যা ঘোষণামূলক লেনদেন সেটআপের ক্ষেত্রে অন্তর্ভুক্ত রয়েছে BeanFactoryTransactionAttributeSourceAdvisor। এর পরিবর্তে অনুরোধ TransactionAttributeSourcePointcut#matches()করা হয়, যা লেনদেন-সম্পর্কিত তথ্য সংগ্রহ করা উচিত। এটি লক্ষ্য শ্রেণিতে উত্তীর্ণ হয়েছে এবং এটি সর্বদা এই শ্রেণীর প্রয়োগকারী সমস্ত ইন্টারফেসকে অতিক্রম করতে পারে। এখন: কেন এটি নির্ভরযোগ্যভাবে কাজ করতে পারে না?
dma_k

4
@ ডিএমএ_কে - জাভা রানটাইম কেবল সুপারক্লাস থেকে উত্তরাধিকার সূত্রে প্রাপ্ত বর্গ টীকাগুলিতে সরাসরি প্রবেশাধিকার দেয়, বা কোনও উত্তরাধিকার না করে পদ্ধতি টীকা দেয়। সুতরাং পয়েন্টকুট.ম্যাচস () আসলে সমস্ত ইন্টারফেসকে অবিচ্ছিন্নভাবে অতিক্রম করতে হবে, প্রতিবিম্ব, হ্যান্ডলিং ব্রিজের পদ্ধতি, ওভারলোডিং, ভারার্গস, জেনেরিকস, প্রক্সিগুলি সহ অবশ্যই "বাস্তব" ওভাররাইড পদ্ধতিটি আবিষ্কার করতে হবে এবং অবশ্যই এটি দ্রুত করতে হবে । তারপরে আপনাকে হীরকের উত্তরাধিকার নিয়ে কাজ করতে হবে - সম্ভবত উত্তরাধিকারসূত্রে প্রাপ্ত বহু @Transactionalটিকাগুলির মধ্যে কোনটি প্রয়োগ করা যেতে পারে? সুতরাং, যদিও এটি সব সম্ভব , আমি স্প্রিংকে দোষ দিই না। jira.springsource.org/browse/SPR-975
পিটার ডেভিস

9

আপনি এগুলি ইন্টারফেসে রাখতে পারেন তবে সতর্ক হতে হবে যে কোনও কোনও ক্ষেত্রে লেনদেন শেষ নাও হতে পারে। স্প্রিং ডক্সের সেকশন 10.5.6 এ দ্বিতীয় টিপটি দেখুন :

স্প্রিং সুপারিশ করে যে আপনি কেবলমাত্র কন্ট্রাক্ট ক্লাসগুলি (এবং কংক্রিটের ক্লাসের পদ্ধতিগুলি) @ ট্রানজেকশনাল টীকা সহ এনটেট করার ইন্টারফেসগুলির বিপরীতে টিকা রচনা করুন। আপনি অবশ্যই @ ট্রান্সজেকশনাল টিকাটি একটি ইন্টারফেসে (বা একটি ইন্টারফেস পদ্ধতিতে) রাখতে পারেন, তবে এটি কেবলমাত্র আপনি যেমনটি আশা করেন তা কাজ করে যদি আপনি ইন্টারফেস-ভিত্তিক প্রক্সি ব্যবহার করছেন। জাভা টীকাগুলি ইন্টারফেস থেকে উত্তরাধিকার সূত্রে প্রাপ্ত নয় এর অর্থ হ'ল আপনি যদি ক্লাস-ভিত্তিক প্রক্সি (প্রক্সি-লক্ষ্য-শ্রেণি = "সত্য") বা বুনন-ভিত্তিক দিক (মোড = "অ্যাসপেক্ট") ব্যবহার করেন তবে লেনদেনের সেটিংস প্রক্সিং এবং বুনন অবকাঠামো দ্বারা স্বীকৃত নয় এবং অবজেক্টটি কোনও লেনদেনের প্রক্সিতে আবৃত হবে না, যা সিদ্ধান্তগতভাবে খারাপ হবে।

আমি এ কারণে তাদের বাস্তবায়নে রাখার সুপারিশ করব।

এছাড়াও, আমার কাছে, লেনদেনগুলি বাস্তবায়নের বিশদ হিসাবে মনে হয় তাই তাদের বাস্তবায়ন শ্রেণিতে হওয়া উচিত। লগিং বা পরীক্ষা বাস্তবায়নের জন্য মোড়ক বাস্তবায়ন (মকস) যা ট্রানজেকশনাল হওয়ার দরকার নেই তা কল্পনা করুন।


9

বসন্তের সুপারিশটি হ'ল আপনি একটি ইন্টারফেসের পরিবর্তে কংক্রিটের প্রয়োগগুলি বর্ননা করুন। কোনও ইন্টারফেসে টীকাটি ব্যবহার করা ভুল নয়, কেবলমাত্র সেই বৈশিষ্ট্যটির অপব্যবহার করা এবং অজান্তেই আপনার @ লেনদেনের ঘোষণাকে বাইপাস করা সম্ভব।

যদি আপনি কোনও ইন্টারফেসে লেনদেনের কিছু চিহ্নিত করেছেন এবং তার পরে বসন্তের অন্য কোথাও এর বাস্তবায়নকারী ক্লাসগুলির একটি উল্লেখ করেন তবে এটি স্পষ্ট নয় যে বসন্ত যে বস্তুটি তৈরি করে তা @ ট্রান্সজেকশনাল টীকাকে সম্মান করবে না।

অনুশীলনে এটি দেখতে এমন কিছু দেখাচ্ছে:

public class MyClass implements MyInterface { 

    private int x;

    public void doSomethingNonTx() {}

    @Transactional
    public void toSomethingTx() {}

}

1

কংক্রিট ক্লাসগুলিতে @ লেনদেনকে সমর্থন করছেন:

আমি সাধারণত 3 বিভাগে একটি সমাধান স্থপতি করতে পছন্দ করি: একটি এপিআই, একটি বাস্তবায়ন এবং একটি ওয়েব (প্রয়োজনে)। নির্ভরতা হ্রাস করে যথাসম্ভব হালকা / সরল / POJO হিসাবে রাখার জন্য আমি যথাসাধ্য চেষ্টা করি। এটি বিশেষত গুরুত্বপূর্ণ যদি আপনি এটি বিতরণ / সংহত পরিবেশে খেলেন যেখানে আপনাকে এপিআইগুলি অনেকগুলি ভাগ করতে হয়।

@ ট্রান্সজেকশনাল স্থাপনের জন্য এপিআই বিভাগে স্প্রিং গ্রন্থাগারগুলির প্রয়োজন, যা আইএমএইচও কার্যকর নয়। সুতরাং আমি লেনদেনটি যে বাস্তবায়নে চলছে তাতে এটি যুক্ত করতে পছন্দ করি।


0

TX ডেটা সম্পর্কে আপনার আইএফসি-র সমস্ত আগমনযোগ্য প্রয়োগকারীর যত্ন নেওয়ার ক্ষেত্রে এটি ইন্টারফেসে রাখা ঠিক আছে (লেনদেনগুলি এমন সমস্যা নয় যা কেবল ডেটাবেসগুলিই ডিল করে)। যদি পদ্ধতিটি টিএক্সের বিষয়ে চিন্তা করে না (তবে আপনাকে এটি হাইবারনেট বা যে কোনও কিছুতে লাগাতে হবে), এটি ইমপ্লিট করুন।

এছাড়াও, @Transactionalইন্টারফেসের পদ্ধতিগুলির মধ্যে রাখা আরও ভাল হতে পারে :

public interface FooService {
    @Transactional(readOnly = true)
    void doSmth();
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.