আপনি স্থান উচিত @Transactional
মধ্যে DAO
ক্লাস এবং / অথবা তাদের পদ্ধতি বা এটাকে আরও ভাল পরিষেবা শ্রেণীর যা দাও বস্তু ব্যবহার আহ্বান করা হয় টীকা হয়? বা "স্তরগুলি" উভয়ই বোধগম্য করে তোলে?
আপনি স্থান উচিত @Transactional
মধ্যে DAO
ক্লাস এবং / অথবা তাদের পদ্ধতি বা এটাকে আরও ভাল পরিষেবা শ্রেণীর যা দাও বস্তু ব্যবহার আহ্বান করা হয় টীকা হয়? বা "স্তরগুলি" উভয়ই বোধগম্য করে তোলে?
উত্তর:
আমি মনে করি লেনদেনগুলি পরিষেবা স্তরের অন্তর্ভুক্ত। এটি একমাত্র যা কাজ এবং ব্যবহারের এককগুলির সম্পর্কে জানে। যদি আপনার একক লেনদেনের জন্য একসাথে কাজ করা দরকার এমন কোনও পরিষেবাতে বেশ কয়েকটি ডিএও ইনজেক্ট করা থাকে তবে এটি সঠিক উত্তর।
সাধারণভাবে আমি অন্যদের সাথে একমত হয়ে বলছি যে লেনদেনগুলি সাধারণত পরিষেবা স্তরে শুরু হয় (আপনার অবশ্যই প্রয়োজনীয় গ্রানুলারিটির উপর নির্ভর করে)।
তবে, মাঝামাঝি সময়ে আমি @Transactional(propagation = Propagation.MANDATORY)
আমার ডিএও স্তর (এবং অন্যান্য স্তরগুলিকেও লেনদেন শুরু করার অনুমতি দেওয়া হয় না তবে বিদ্যমান স্তরগুলির প্রয়োজন হয়) যুক্ত করতে শুরু করেছি কারণ আপনি যেখানে কলারে কোনও লেনদেন শুরু করতে ভুলে গিয়েছিলেন সেখানে ত্রুটিগুলি সনাক্ত করা অনেক সহজ "( যেমন পরিষেবা)। যদি আপনার ডিএও বাধ্যতামূলক প্রচারের সাথে টীকাযুক্ত হয় তবে আপনি একটি ব্যতিক্রম পাবেন যা উল্লেখ করে যে পদ্ধতিটি চালু করার সময় কোনও সক্রিয় লেনদেন নেই।
আমার একটি ইন্টিগ্রেশন টেস্টও রয়েছে যেখানে আমি এই টীকাটির জন্য সমস্ত মটরশুটি (শিম পোস্ট প্রসেসর) পরীক্ষা করে দেখি এবং যদি সেখানে থাকে তবে ব্যর্থ হয় @Transactional
কোনও শিমের মধ্যে ম্যান্ডেটরি ব্যতীত অন্য প্রচারের সাথে টিকা থাকে যা পরিষেবা স্তরের সাথে সম্পর্কিত নয়। এইভাবে আমি নিশ্চিত করি যে আমরা ভুল স্তরে লেনদেন শুরু করব না।
@Transactional
পরিষেবা বাস্তবায়ন ক্লাস করা উচিত, এবং আমার @Transactional(propagation = MANDATORY)
ডিএও (সংগ্রহস্থল) শ্রেণি প্রয়োগ করা উচিত?
লেনদেনমূলক টীকাগুলি অবিচ্ছেদ্য এমন সমস্ত ক্রিয়াকলাপের চারপাশে রাখা উচিত।
উদাহরণস্বরূপ, আপনার কলটি "পাসওয়ার্ড পরিবর্তন করুন"। এটি দুটি অপারেশন নিয়ে গঠিত
সুতরাং উপরের হিসাবে, অডিট যদি ব্যর্থ হয়, তবে পাসওয়ার্ড পরিবর্তনও ব্যর্থ হওয়া উচিত? যদি তা হয় তবে লেনদেনের পরিমাণ 1 এবং 2 এর মধ্যে হওয়া উচিত (সুতরাং পরিষেবা স্তরে)। যদি ইমেল ব্যর্থ হয় (সম্ভবত এটির জন্য কোনও প্রকারের নিরাপদ ব্যর্থ হওয়া উচিত যাতে এটি ব্যর্থ হয় না) তবে এটির পরিবর্তনের পাসওয়ার্ড এবং নিরীক্ষণের পিছনে ফিরে আসা উচিত?
কোথায় রাখবেন তা সিদ্ধান্ত নেওয়ার সময় এগুলি আপনাকে জিজ্ঞাসা করা উচিত @Transactional
।
Traditionalতিহ্যবাহী স্প্রিং আর্কিটেকচারের সঠিক উত্তর হ'ল সার্ভিস ক্লাসগুলিতে লেনদেনের শব্দার্থবিদ্যা স্থাপন করা, যে কারণে অন্যরা ইতিমধ্যে বর্ণনা করেছে।
বসন্তে একটি উদীয়মান প্রবণতা ডোমেন-চালিত ডিজাইন (ডিডিডি) এর দিকে। স্প্রিং রু খুব সুন্দরভাবে ট্রেন্ডটির উদাহরণ দেয়। ধারণা ডোমেইন বস্তুর POJOs অনেক করা হয় সমৃদ্ধ টিপিক্যাল বসন্ত আর্কিটেকচারের (সাধারণত তারা চেয়ে তারা রক্তহীন ) এবং বিশেষত নিজেরাই ডোমেন অবজেক্টে লেনদেন এবং শব্দার্থক শব্দগুলি রাখে। কেবলমাত্র প্রয়োজনীয় CRUD অপারেশনগুলির ক্ষেত্রে ওয়েব কন্ট্রোলাররা সরাসরি ডোমেন অবজেক্ট POJOs এ কাজ করে (তারা এই প্রসঙ্গে সত্তা হিসাবে কাজ করছে), এবং কোনও পরিষেবা স্তর নেই। ক্ষেত্রে যেখানে ডোমেন অবজেক্টগুলির মধ্যে এক ধরণের সমন্বয় প্রয়োজন, আপনার সাথে একটি পরিষেবা বিন বিন্যাস থাকতে পারে@Transaction
.তিহ্য অনুসারে আপনি ডোমেন অবজেক্টগুলিতে এমন কিছুতে লেনদেনের প্রসারণ সেট করতে পারেন REQUIRED
যাতে ডোমেন অবজেক্টগুলি যে কোনও বিদ্যমান লেনদেন, যেমন পরিষেবা বিনে শুরু হওয়া লেনদেন ব্যবহার করে।
প্রযুক্তিগতভাবে এই কৌশলটি AspectJ এবং ব্যবহার করে <context:spring-configured />
। রু ডোমেন অবজেক্ট স্টাফ (মূলত ক্ষেত্র এবং ব্যবসায়ের পদ্ধতি) থেকে সত্তা শব্দার্থবিজ্ঞান (লেনদেন এবং দৃistence়তা) পৃথক করতে AspectJ আন্ত-টাইপ সংজ্ঞা ব্যবহার করে।
সাধারন কেসটি কোনও পরিষেবা স্তর স্তরে টিকা দেওয়া হবে তবে এটি আপনার প্রয়োজনীয়তার উপর নির্ভর করে।
সার্ভিস লেয়ারে টীকা না দেওয়ার ফলে ডিএও স্তরের ক্ষেত্রে মন্তব্য করার চেয়ে বেশি লেনদেন হবে in লেনদেনের বিচ্ছিন্নতার স্তরের উপর নির্ভর করে যা আপনাকে সমস্যাগুলি করতে পারে, যেমন সমবর্তী লেনদেনগুলি একে অপরের পরিবর্তনগুলি দেখতে পাবে না। পুনরাবৃত্তি পড়ুন।
ডিএওগুলিতে টীকা না দেওয়ার কারণে লেনদেনগুলি যতটা সম্ভব সংক্ষিপ্ত থাকবে, আপনার পরিষেবা স্তরটি যে কার্যকারিতাটি প্রকাশ করছে তা একটি একক (রোলব্যাকেবল) লেনদেনে হবে না with
প্রচারের মোডটি ডিফল্ট হিসাবে সেট করা থাকলে উভয় স্তরকে টিকিয়ে দেওয়া কোনও অর্থবোধ করে না।
আমি স্থান @Transactional
উপর @Service
লেয়ার এবং সেট rollbackFor
কোনো ব্যতিক্রম এবং readOnly
আরও লেনদেন নিখুত।
গতানুগতিক @Transactional
কেবল RuntimeException
(চেনা ব্যতিক্রমগুলি) অনুসন্ধান করা হবে, এতে রোলব্যাক সেট করে Exception.class
(পরীক্ষিত ব্যতিক্রমগুলি) এটি কোনও ব্যতিক্রমের জন্য রোলব্যাক করবে।
@Transactional(readOnly = false, rollbackFor = Exception.class)
বা "স্তরগুলি" উভয়ই বোধগম্য করে তোলে? - সার্ভিস লেয়ার এবং দাও স্তর উভয়ই বর্ননা করা কোনও অর্থবোধ করে না - যদি কেউ নিশ্চিত করতে চান যে ডিএও পদ্ধতিতে সর্বদা ডিএওতে "বাধ্যতামূলক" প্রচার সহ একটি পরিষেবা স্তর থেকে ডেকে আনা হয় (প্রচারিত হয়)। এটি ডিআইও পদ্ধতিগুলির জন্য ইউআই স্তর (বা নিয়ন্ত্রণকারী) থেকে ডেকে কিছুটা নিষেধাজ্ঞার ব্যবস্থা করবে। এছাড়াও - যখন ইউনিটের বিশেষত ডিএও স্তর পরীক্ষা করা হয় - ডিএও টীকা দেওয়া থাকে তা লেনদেনের কার্যকারিতার জন্য এটি পরীক্ষা করাও নিশ্চিত করে tested
propagation=Propagation.REQUIRES_NEW
। অন্যথায় প্রোপোগেশন = বাধ্যতামূলক সহ বেশিরভাগ ক্ষেত্রে ডিএও কেবল পরিষেবা স্তর দ্বারা শুরু হওয়া বিদ্যমান লেনদেনে অংশ নেবে।
এছাড়াও, স্প্রিং কেবলমাত্র কংক্রিটের ক্লাসে টীকা ব্যবহার করার পরামর্শ দেয় এবং ইন্টারফেস নয়।
http://static.springsource.org/spring/docs/2.0.x/reference/transaction.html
ডাটাবেস স্তরে লেনদেনের জন্য
বেশিরভাগ ক্ষেত্রে আমি @Transactional
ডিএও-র কেবলমাত্র পদ্ধতি স্তরে ব্যবহার করেছি, সুতরাং কনফিগারেশনটি কোনও পদ্ধতির জন্য / ডিফল্ট ব্যবহারের জন্য বিশেষত প্রয়োজন (প্রয়োজনীয়)
ডিএও'র পদ্ধতি যা ডেটা আনতে (নির্বাচন করুন ..) - এর দরকার
@Transactional
নেই লেনদেন ইন্টারসেপটার / এবং এওপি প্রক্সির কারণেই এটি সম্পাদন করা দরকার যা কিছু ওভারহেডের দিকে নিয়ে যায়।
ডিএও'র পদ্ধতিগুলি যা সন্নিবেশ / আপডেট করে তা পাবে @Transactional
রূপান্তরকারী খুব ভাল ব্লগ
অ্যাপ্লিকেশন স্তরের জন্য -
আমি ব্যবসায়িক যুক্তির জন্য লেনদেন ব্যবহার করছি আমি অপ্রত্যাশিত ত্রুটির ক্ষেত্রে রোলব্যাক সক্ষম হতে চাই
@Transactional(rollbackFor={MyApplicationException.class})
public void myMethod(){
try {
//service logic here
} catch(Throwable e) {
log.error(e)
throw new MyApplicationException(..);
}
}
Transactional
ইন সম্পর্কে +1 খুব সুন্দর নিবন্ধJava
সাধারণত, একটিকে পরিষেবার স্তরে একটি লেনদেন করা উচিত।
তবে যেমনটি আগেই বলা হয়েছে, কোনও অপারেশনের পারমাণবিকতাই আমাদের জানান যে যেখানে কোনও টীকাটি প্রয়োজনীয়। সুতরাং, আপনি যদি হাইবারনেটের মতো ফ্রেমওয়ার্কগুলি ব্যবহার করেন, যেখানে কোনও একক "একক সংরক্ষণ / আপডেট / মুছুন / ... পরিবর্তন" অপারেশনটিতে বেশ কয়েকটি সারণিতে কয়েকটি সারি (বস্তুর গ্রাফের মাধ্যমে ক্যাসকেডের কারণে) পরিবর্তন করার সম্ভাবনা রয়েছে অবশ্যই এই নির্দিষ্ট ডিএও পদ্ধতিতে লেনদেন পরিচালনা থাকতে হবে।
@Transactional
অবিচ্ছেদ্য যে সমস্ত ক্রিয়াকলাপকে ঘিরে টীকাগুলি স্থাপন করা উচিত। @Transactional
লেনদেনের প্রসারণ ব্যবহার করে স্বয়ংক্রিয়ভাবে পরিচালিত হয় this এই ক্ষেত্রে যদি বর্তমান পদ্ধতি দ্বারা অন্য কোনও পদ্ধতি কল করা হয়, তবে সেই পদ্ধতিতে চলমান লেনদেনে যোগদানের বিকল্প থাকবে।
সুতরাং উদাহরণ দেওয়া যাক:
আমাদের কাছে 2 টি মডেলের অর্থাত্ Country
এবং City
। রিলেশনাল ম্যাপিং Country
এবং City
মডেলটি একের মতো Country
একাধিক শহর থাকতে পারে তাই ম্যাপিংয়ের মতো,
@OneToMany(fetch = FetchType.LAZY, mappedBy="country")
private Set<City> cities;
এখানে দেশ আনার সাথে একাধিক শহরে ম্যাপ করা হয়েছে Lazily
। সুতরাং এখানে @Transactinal
যখন আমরা ডাটাবেস থেকে দেশ অবজেক্টটি পুনরুদ্ধার করি তখন আমরা দেশের অবজেক্টের সমস্ত ডেটা পাব তবে শহরগুলির সেট পাব না কারণ আমরা শহরগুলি আনছি LAZILY
।
//Without @Transactional
public Country getCountry(){
Country country = countryRepository.getCountry();
//After getting Country Object connection between countryRepository and database is Closed
}
যখন আমরা দেশের অবজেক্ট থেকে নগরগুলির সেট অ্যাক্সেস করতে চাই তখন আমরা সেই সেটে নালাগুলি পেয়ে যাব কারণ সেটটি কেবলমাত্র এই সেটটি তৈরি করেছে সেটের মানগুলি পেতে কেবলমাত্র সেটের ডেটা দিয়ে আরম্ভ করা হয় না @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
আসলে কী তা তার ব্যাখ্যা
@Transactional
সেবা স্তরে ব্যবহার করা উচিত যেমন ব্যবসা লজিক রয়েছে। ডিএও স্তরটিতে সাধারণত কেবল ডাটাবেস সিআরইউডি অপারেশন থাকে।
// 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
এখানে উপস্থিত বেশিরভাগ ব্যবসায়িক যুক্তি হিসাবে টীকাগুলি , এতে বিশদ স্তরের ব্যবহার-কেস আচরণ রয়েছে।
ধরুন আমরা এটি ডিএওতে যুক্ত করেছি এবং পরিষেবা থেকে আমরা 2 ডিএও ক্লাস কল করছি, একটি ব্যর্থ এবং অন্য সাফল্য, এক্ষেত্রে যদি @Transactional
পরিষেবা না একজন ডিবি অঙ্গীকারবদ্ধ এবং অন্যটি রোলব্যাক করবে।
সুতরাং আমার প্রস্তাবটি হ'ল এই টীকাকে বিজ্ঞতার সাথে ব্যবহার করুন এবং কেবল পরিষেবা স্তরটিতে ব্যবহার করুন at
সব আসুন প্রথম সংজ্ঞায়িত যেখানে আমরা ব্যবহার করতে হবে লেনদেনের ?
আমি মনে করি সঠিক উত্তরটি হল - যখন আমাদের এটি নিশ্চিত করা দরকার যে একটি পারমাণবিক ক্রিয়াকলাপ হিসাবে ক্রিয়াগুলির ক্রম একসাথে শেষ হবে বা কোনও ক্রিয়ায় ব্যর্থ হয়েও কোনও পরিবর্তন করা হবে না।
ব্যবসায়িক যুক্তিগুলিকে পরিষেবাগুলিতে স্থাপন করা সর্বজনবিদিত practice সুতরাং পরিষেবা পদ্ধতিতে বিভিন্ন ক্রিয়া থাকতে পারে যা কাজের একক লজিকাল ইউনিট হিসাবে সম্পাদন করা আবশ্যক। যদি তাই হয় - তবে এই জাতীয় পদ্ধতিটি অবশ্যই লেনদেন হিসাবে চিহ্নিত করতে হবে । অবশ্যই, প্রতিটি পদ্ধতিতে এ জাতীয় সীমাবদ্ধতার প্রয়োজন হয় না, সুতরাং আপনার পুরো পরিষেবাটি লেনদেন হিসাবে চিহ্নিত করার দরকার নেই ।
এবং আরও বেশি - এই অ্যাকাউন্টটি নিতে ভুলবেন না যে @ স্পষ্টতই লেনদেন পদ্ধতি পদ্ধতির কার্যকারিতা হ্রাস করতে পারে। পুরো ছবিটি দেখতে আপনাকে লেনদেনের বিচ্ছিন্নতা স্তরগুলি জানতে হবে। এটি জেনে যাওয়া আপনাকে @ ট্রানজেকশনাল যেখানে এটির প্রয়োজন নেই সেখানে ব্যবহার এড়াতে সহায়তা করতে পারে ।
@ ট্রানজেকশনালকে ডিএও এবং পরিষেবা স্তরটির মধ্যে একটি পৃথক মাঝারি স্তরে রাখা আরও ভাল । যেহেতু, রোলব্যাকটি অত্যন্ত গুরুত্বপূর্ণ, আপনি আপনার সমস্ত ডিবি ম্যানিপুলেশনটি মাঝের স্তরে রেখে সার্ভিস লেয়ারে ব্যবসায়িক যুক্তি লিখতে পারেন। মাঝারি স্তরটি আপনার ডিএও স্তরগুলির সাথে যোগাযোগ করবে।
এটি আপনাকে ObjectOptimisticLockingFailureException- এর মতো অনেক পরিস্থিতিতে সহায়তা করবে - আপনার লেনদেন শেষ হয়ে গেলেই এই ব্যতিক্রম ঘটে। সুতরাং, আপনি এটি মাঝারি স্তরে ধরতে পারবেন না তবে আপনি এখন আপনার পরিষেবা স্তরটি ধরতে পারেন। আপনার যদি পরিষেবার স্তরে @ লেনদেন হয় তবে এটি সম্ভব হবে না। যদিও আপনি কন্ট্রোলারে ধরতে পারেন তবে কন্ট্রোলার যতটা সম্ভব পরিষ্কার হওয়া উচিত।
সমস্ত সেভ, ডিলিট এবং আপডেট অপশনগুলি শেষ করার পরে যদি আপনি আলাদা থ্রেডে মেল বা এসএমএস প্রেরণ করছেন তবে আপনার মধ্য স্তরতে লেনদেন শেষ হওয়ার পরে আপনি পরিষেবাতে এটি করতে পারেন। আবার, আপনি যদি পরিষেবার স্তরে @ লেনদেনের কথা উল্লেখ করেন তবে আপনার লেনদেন ব্যর্থ হলেও আপনার মেলটি চলে যাবে।
সুতরাং মাঝারি @ লেনদেনের স্তরটি আপনার কোডটিকে আরও ভাল এবং পরিচালনা করা সহজ করে তুলবে। অন্যথায়, আপনি যদি ডিএও স্তর ব্যবহার করেন তবে আপনি সমস্ত ক্রিয়াকলাপ রোলব্যাক করতে পারবেন না। আপনি যদি পরিষেবা স্তর ব্যবহার করেন তবে আপনাকে কিছু ক্ষেত্রে এওপি (অ্যাসপেক্ট ওরিয়েন্টেড প্রোগ্রামিং) ব্যবহার করতে হতে পারে ।
আদর্শভাবে, পরিষেবা স্তর (ম্যানেজার) আপনার ব্যবসায়ের যুক্তি উপস্থাপন করে এবং তাই এটি দিয়ে @Transactional
এনেট করা উচিত ervice এমন কোনও পরিস্থিতি ধরে নেওয়া যাক যেখানে কোনও পরিষেবা পদ্ধতিতে আপনার কাছে NA নম্বর অপারেশন রয়েছে। যদি আপনার 1 ম ডিএও অপারেশন ব্যর্থ হয়, অন্যরা এখনও পাস হতে পারে এবং আপনি অসামঞ্জস্যপূর্ণ ডিবি স্থিতি অর্জন করবেন। পরিষেবা স্তরকে টীকা না দেওয়া আপনাকে এ জাতীয় পরিস্থিতি থেকে বাঁচাতে পারে।
আমি @Transactional
পদ্ধতি স্তরে পরিষেবা স্তর ব্যবহার করতে পছন্দ করি ।