synchronized
জাভা কীওয়ার্ড কীভাবে কাজ করে
আপনি যখন synchronized
একটি স্ট্যাটিক পদ্ধতিতে কীওয়ার্ডটি যুক্ত করেন , তখন পদ্ধতিটি কেবল একবারে একটি থ্রেড দ্বারা কল করা যেতে পারে।
আপনার ক্ষেত্রে, প্রতিটি পদ্ধতির কল এই করবে:
- নতুন একটি তৈরি কর
SessionFactory
- নতুন একটি তৈরি কর
Session
- সত্তা আনুন
- সত্তাকে কলারে ফিরিয়ে দিন
তবে এগুলি আপনার প্রয়োজনীয়তা ছিল:
- একই ডিবি উদাহরণটিতে তথ্য অ্যাক্সেস রোধ করতে আমি এটি চাই।
getObjectById
যখন কোনও নির্দিষ্ট শ্রেণীর দ্বারা ডাকা হয় তখন সমস্ত ক্লাসের জন্য ডেকে আটকানো
সুতরাং, getObjectById
পদ্ধতিটি থ্রেড-নিরাপদ হলেও বাস্তবায়নটি ভুল।
SessionFactory
সেরা অনুশীলন
SessionFactory
থ্রেড-নিরাপদ, এবং এটা যেমন সত্তা শ্রেণীর পার্স এবং অভ্যন্তরীণ সত্তা metamodel উপস্থাপনা গড়ে তুলতে প্রয়োজন তৈরি করতে একটি খুব ব্যয়বহুল বস্তু আছে।
সুতরাং, আপনার SessionFactory
প্রতিটি getObjectById
পদ্ধতি কল চালু করা উচিত নয় ।
পরিবর্তে, আপনার এটির জন্য একটি সিঙ্গলটন উদাহরণ তৈরি করা উচিত।
private static final SessionFactory sessionFactory = new Configuration()
.configure()
.buildSessionFactory();
Session
সবসময় বন্ধ করে দেওয়া উচিত
আপনি Session
কোনও finally
ব্লকটি বন্ধ করেননি এবং সত্তা লোড করার সময় যদি কোনও ব্যতিক্রম ছুঁড়ে দেওয়া হয় তবে এটি ডাটাবেস সংস্থানগুলি ফাঁস করতে পারে।
Session.load
পদ্ধতি অনুসারে জাভাডক একটি নিক্ষেপ HibernateException
করতে পারে যদি সত্তাটি ডাটাবেসে পাওয়া যায় না।
কোনও উদাহরণ উপস্থিত রয়েছে কিনা তা স্থির করার জন্য আপনার এই পদ্ধতিটি ব্যবহার করা উচিত নয় ( get()
পরিবর্তে ব্যবহার করুন)। এটি কেবলমাত্র অনুমান করে যে আপনার অস্তিত্ব রয়েছে তা পুনরুদ্ধার করতে এটি ব্যবহার করুন, যেখানে অস্তিত্বই একটি আসল ত্রুটি হবে।
এজন্য আপনাকে এটিকে finally
বন্ধ করার জন্য একটি ব্লক ব্যবহার করতে হবে Session
:
public static synchronized Object getObjectById (Class objclass, Long id) {
Session session = null;
try {
session = sessionFactory.openSession();
return session.load(objclass, id);
} finally {
if(session != null) {
session.close();
}
}
}
বহু-থ্রেড অ্যাক্সেস প্রতিরোধ করা
আপনার ক্ষেত্রে, আপনি নিশ্চিত করতে চেয়েছিলেন যে কেবল একটি থ্রেড সেই নির্দিষ্ট সত্তায় অ্যাক্সেস পেয়েছে।
তবে synchronized
কীওয়ার্ডটি কেবল দুটি থ্রেডকে getObjectById
একই সাথে কল করতে বাধা দেয় । দুটি থ্রেড যদি একের পর এক এই পদ্ধতিটিকে কল করে তবে আপনার এই সত্তাটি ব্যবহার করে এখনও দুটি থ্রেড থাকবে।
সুতরাং, আপনি যদি কোনও প্রদত্ত ডাটাবেস অবজেক্টটি লক করতে চান যাতে অন্য কোনও থ্রেড এটি পরিবর্তন করতে না পারে, তবে আপনাকে ডাটাবেস লকগুলি ব্যবহার করতে হবে।
synchronized
মূলশব্দটি কেবল একটি একক জেভিএম-এ কাজ করে। আপনার যদি একাধিক ওয়েব নোড থাকে তবে এটি একাধিক জেভিএম জুড়ে মাল্টি-থ্রেড অ্যাক্সেসকে আটকাবে না।
আপনি কি করতে প্রয়োজন ব্যবহার LockModeType.PESSIMISTIC_READ
বাLockModeType.PESSIMISTIC_WRITE
যখন ডিবি পরিবর্তন, ভালো প্রয়োগের:
Session session = null;
EntityTransaction tx = null;
try {
session = sessionFactory.openSession();
tx = session.getTransaction();
tx.begin();
Post post = session.find(
Post.class,
id,
LockModeType.LockModeType.PESSIMISTIC_READ
);
post.setTitle("High-Performance Java Perisstence");
tx.commit();
} catch(Exception e) {
LOGGER.error("Post entity could not be changed", e);
if(tx != null) {
tx.rollback();
}
} finally {
if(session != null) {
session.close();
}
}
সুতরাং, আমি এটিই করেছি:
- আমি একটি নতুন তৈরি করেছি
EntityTransaction
এবং একটি নতুন ডাটাবেস লেনদেন শুরু করেছি
Post
সম্পর্কিত ডাটাবেস রেকর্ডটিতে একটি লক ধরে রাখার সময় আমি সত্তাটি লোড করেছি
- আমি
Post
সত্তাটি পরিবর্তন করেছি এবং লেনদেনের প্রতিশ্রুতিবদ্ধ
Exception
নিক্ষিপ্ত হওয়ার ক্ষেত্রে , আমি লেনদেনটি ফিরিয়ে আনি
এসিডি এবং ডাটাবেস লেনদেন সম্পর্কে আরও তথ্যের জন্য, এই নিবন্ধটিও পরীক্ষা করে দেখুন ।