প্রথম স্থানে শুধুমাত্র মন্তব্য করার জন্য দুঃখিত, তবে আমি প্রায় প্রতিদিন একই ধরণের মন্তব্য পোস্ট করছি যেহেতু অনেক লোক মনে করে যে ডিবি-ক্লাসে ADO.NET কার্যকারিতা আবদ্ধ করা স্মার্ট হবে (আমারও 10 বছর আগে)। বেশিরভাগ ক্ষেত্রে তারা স্থির / ভাগ করা অবজেক্টগুলি ব্যবহার করার সিদ্ধান্ত নেয় যেহেতু কোনও ক্রিয়াকলাপের জন্য কোনও নতুন অবজেক্ট তৈরি করা তার চেয়ে দ্রুত বলে মনে হয়।
এটি পারফরম্যান্সের ক্ষেত্রে বা ব্যর্থ-সুরক্ষার দিক থেকে ভাল ধারণা নয়।
সংযোগ-পুলের অঞ্চলে পোচ করবেন না
ADO.NET অভ্যন্তরীণভাবে ADO-NET সংযোগ-পুলে DBMS- র অন্তর্নিহিত সংযোগগুলি পরিচালনা করার একটি ভাল কারণ রয়েছে :
অনুশীলনে, বেশিরভাগ অ্যাপ্লিকেশন সংযোগগুলির জন্য কেবল একটি বা কয়েকটি আলাদা কনফিগারেশন ব্যবহার করে। এর অর্থ হ'ল অ্যাপ্লিকেশন কার্যকর করার সময়, অনেকগুলি অভিন্ন সংযোগ বারবার খোলা এবং বন্ধ করা হবে। সংযোগ খোলার ব্যয়কে হ্রাস করতে, ADO.NET সংযোগ পুলিং নামে একটি অপ্টিমাইজেশন কৌশল ব্যবহার করে।
সংযোগ পুলিং নতুন সংযোগগুলি খোলার পরিমাণটি হ্রাস করে। পুলার দৈহিক সংযোগের মালিকানা বজায় রাখে। এটি প্রতিটি প্রদত্ত সংযোগ কনফিগারেশনের জন্য সক্রিয় সংযোগের সেটকে জীবিত রেখে সংযোগ পরিচালনা করে। যখনই কোনও ব্যবহারকারী কোনও সংযোগে ওপেন কল করে, পুলারটি পুলটিতে একটি উপলব্ধ সংযোগের সন্ধান করে। যদি কোনও পুলযুক্ত সংযোগ উপলব্ধ থাকে তবে এটি নতুন সংযোগ খোলার পরিবর্তে এটি কলারের কাছে ফেরত দেয়। অ্যাপ্লিকেশনটি যখন সংযোগে ক্লোজকে কল করে, পুলার এটিকে বন্ধ না করে সক্রিয় সংযোগগুলির পুলযুক্ত সেটটিতে ফেরত দেয়। একবার সংযোগটি পুলটিতে ফিরে আসার পরে এটি পরবর্তী ওপেন কলে পুনরায় ব্যবহারের জন্য প্রস্তুত।
সুতরাং স্পষ্টতই সংযোগ তৈরি করা, খোলার বা বন্ধ হওয়া এড়াতে হবে না কারণ বাস্তবে সেগুলি তৈরি করা, খোলা এবং বন্ধ করা হয়নি। সংযোগ পুলের জন্য এটি "কেবল" একটি পতাকা যা কখন সংযোগটি পুনরায় ব্যবহার করা যায় বা না তা জানতে। তবে এটি একটি অত্যন্ত গুরুত্বপূর্ণ পতাকা, কারণ যদি কোনও সংযোগটি "ব্যবহারে" হয় (সংযোগ পুলটি ধরে নেওয়া হয়) তবে একটি নতুন শারীরিক সংযোগ অবশ্যই ডিবিএমএসের জন্য খুব ব্যয়বহুল হতে হবে।
সুতরাং আপনি কোনও কার্যকারিতা উন্নতি করতে পারছেন তবে বিপরীত। যদি সর্বাধিক পুলের আকার নির্দিষ্ট করা হয় (100 টি ডিফল্ট হয়) তবে আপনি ব্যতিক্রম পেতে পারেন (অনেকগুলি মুক্ত সংযোগ ...) ... সুতরাং এটি কেবল পারফরম্যান্সকে মারাত্মকভাবে প্রভাবিত করবে না তবে এটি একটি দুষ্ট ত্রুটির জন্য এবং (লেনদেন ব্যবহার না করে) ডেটা-ডাম্পিং-এরিয়ার জন্য উত্স হয়ে উঠবে।
এমনকি যদি আপনি স্থিতিশীল সংযোগগুলি ব্যবহার করে থাকেন তবে আপনি এই বিষয়টিকে অ্যাক্সেস করার চেষ্টা করে প্রতিটি থ্রেডের জন্য একটি লক তৈরি করছেন। এএসপি.এনইটি প্রকৃতি অনুসারে একটি বহুগঠনের পরিবেশ। সুতরাং এই লকগুলির জন্য দুর্দান্ত সুযোগ রয়েছে যা সর্বোত্তমভাবে পারফরম্যান্স সমস্যার কারণ হয়। প্রকৃতপক্ষে খুব শীঘ্রই আপনি অনেকগুলি ব্যতিক্রম পাবেন (যেমন আপনার এক্সিকিউটিআরডারের জন্য একটি উন্মুক্ত এবং উপলভ্য সংযোগ প্রয়োজন )।
উপসংহার :
- সংযোগ বা কোনও ADO.NET বস্তু একেবারে পুনরায় ব্যবহার করবেন না।
- এগুলিকে স্থিত / ভাগ করে নেবেন না (VB.NET এ)
- সর্বদা তৈরি করুন, খুলুন (সংযোগের ক্ষেত্রে) আপনার যেখানে যেখানে প্রয়োজন সেখানে ব্যবহার করুন, বন্ধ করুন এবং নিষ্পত্তি করুন (কোনও পদ্ধতিতে ফি)
- ব্যবহার
using-statement
মীমাংসা করা এবং বন্ধ (সংযোগ ক্ষেত্রে) implicitely
এটি কেবল সংযোগগুলির জন্যই নয় (যদিও সবচেয়ে উল্লেখযোগ্য)। প্রতিটি অবজেক্ট বাস্তবায়ন করার জন্য নাম তালিকাতে আরও IDisposable
সহজ সমাধান করা উচিত ।using-statement
System.Data.SqlClient
উপরের সমস্তগুলি একটি কাস্টম ডিবি-শ্রেণির বিরুদ্ধে কথা বলে যা সমস্ত বস্তুকে আবদ্ধ করে এবং পুনরায় ব্যবহার করে। এ কারণেই আমি এটিকে আবর্জনাতে মন্তব্য করেছি। এটি কেবল একটি সমস্যার উত্স।
সম্পাদনা করুন : এখানে আপনার- retrievePromotion
আদর্শের একটি সম্ভাব্য বাস্তবায়ন :
public Promotion retrievePromotion(int promotionID)
{
Promotion promo = null;
var connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["MainConnStr"].ConnectionString;
using (SqlConnection connection = new SqlConnection(connectionString))
{
var queryString = "SELECT PromotionID, PromotionTitle, PromotionURL FROM Promotion WHERE PromotionID=@PromotionID";
using (var da = new SqlDataAdapter(queryString, connection))
{
// you could also use a SqlDataReader instead
// note that a DataTable does not need to be disposed since it does not implement IDisposable
var tblPromotion = new DataTable();
// avoid SQL-Injection
da.SelectCommand.Parameters.Add("@PromotionID", SqlDbType.Int);
da.SelectCommand.Parameters["@PromotionID"].Value = promotionID;
try
{
connection.Open(); // not necessarily needed in this case because DataAdapter.Fill does it otherwise
da.Fill(tblPromotion);
if (tblPromotion.Rows.Count != 0)
{
var promoRow = tblPromotion.Rows[0];
promo = new Promotion()
{
promotionID = promotionID,
promotionTitle = promoRow.Field<String>("PromotionTitle"),
promotionUrl = promoRow.Field<String>("PromotionURL")
};
}
}
catch (Exception ex)
{
// log this exception or throw it up the StackTrace
// we do not need a finally-block to close the connection since it will be closed implicitely in an using-statement
throw;
}
}
}
return promo;
}