PDA

View Full Version : بهینه سازی در یک موضوع مربوط به دیتابیس(؟)



koosha system
دوشنبه 17 مهر 1385, 16:33 عصر
من سر در نیاوردم که وقتی می خواهیم یک ثبت نام انجام دهیم یا .... وقتی بر روی دکمه کلیک می شود باید این فرایند ها اجرا شوند:(همه ی کارها در اکشن دکمه)
1: دیتابیس باز شود
2: فلان ....
3: دیتابیس بسته شود

این باز و بسته کردن زیادیه.
نمیشه دیتابیس رو باز نگه داشت؟ من 100 تا دکمه دارم.یکی رو 100 تاش کلیک کنه 100 بار دیتابیس باز و بسته می شه.پس نشد کار
با هیت هم که نمیشه.(پیج لود شد باز بشه)
Cache هم که نمی شه.چون آپدیت می شه و ...
پس؟

SalarSoft
دوشنبه 17 مهر 1385, 18:46 عصر
البته مسئله connection pooling تا حدی مشکل رو حل کرده.

به هر حال من در یکی از سایتها برای حل این مشکل از Session استفاده کرده بودم و خیلی خوب هم جواب داد:
در رویداد PreRequestHandlerExecute مربوط به Global.asax کانکشن رو ایجاد میکنم و در Session ذخیره میکنم.
در مواقع مورد نیاز اون رو از session بازیابی میکنم. قبل از هر استفاده باید از باز بودن کانکشن اطمینان پیدا کنیم و نیازی به بستن کانکشن نیست چون اون رو تو ریداد PostRequestHandlerExecute مربروط به global.asax می بندیم.

در حقیقت در این روش شما برای کل سایت یک کانکشن خواهید که از آغاز درخواست تا پایان اون در اختیار خواهد بود.

mahdi_negahi
دوشنبه 17 مهر 1385, 19:13 عصر
خوب اگر یک نفر با اصلا چند کاربر به چند صفحه مجزا که کار با دیتا بیس دارند این صفحات چی میشه این طور که شما میگید فشار میاد به سرور

koosha system
دوشنبه 17 مهر 1385, 20:29 عصر
میشه در مورد connection pooling توضیح بدید...

{خوب اگر یک نفر با اصلا چند کاربر به چند صفحه مجزا که کار با دیتا بیس دارند این صفحات چی میشه این طور که شما میگید فشار میاد به سرور}
اصلا نفهمیدم منظور این جملتون چیه!

mahdi_negahi
دوشنبه 17 مهر 1385, 21:13 عصر
خوب ملومه اساسا مایکروسافت با اینکه کانکشن ها برای مدتی باز باشند مخالف درباره connection pooling هم سرچ کنید یک مقاله بسیار مفید وجود دارد

mehdi58
دوشنبه 17 مهر 1385, 23:30 عصر
این هم چند تا لینک از Connection pooling

http://barnamenevis.org/forum/showthread.php?t=33592&highlight=connection+pooling

http://barnamenevis.org/forum/showthread.php?t=24152&highlight=connection+pooling

http://barnamenevis.org/forum/showthread.php?t=38995&highlight=connection+pooling

koosha system
سه شنبه 18 مهر 1385, 18:55 عصر
پس مشکلی نیست ما هر بار باز کنیم دیتابیس رو.
آپتیمایز رو MS-SQL انجام میده.درسته؟

mahdi_negahi
سه شنبه 18 مهر 1385, 23:27 عصر
بله ولی توجه به این نکته الزامی است که باید Connection String یکی باشد

pegasos
چهارشنبه 19 مهر 1385, 09:23 صبح
با درود.

بابا من متوجه نمی شوم در این تالار چه می گذرد.
خیلی وقت است که برنامه نویسان Distributed به سمت دیتا بیس DisConnected مهاجرت کرده اند. حالا ما اومدیم و بحث می کنیم که چرا اینطوری شده است.
اگر تکنولوژی های قدیمی ارتباط با دیتا بیس را به خاطر بیاورید، قبل از RDO و ADO می بینید که یک کانکشن مرتبط چه منابع سنگینی از سرور می گیرد و چه مشکلاتی برای برنامه نویس و معمار به وجود می آورد.
حتی در حال حاضر دیتا بیس DesktopApp های هم به صورت DisConnected است.
بعد شما آمده اید بروی ASP.Net که خود معماری این تکنولوژی به صورت منفصل است [یعنی حتی شما به کلاینت خودتان دید ندارید و وقتی جواب کلاینت را دادید ارتباطتان قطع می شود]
می گویید چرا باید این همه Connection باز و بسته کرد.
ببینم شما که کانکشن را باز نگه می دارید. اصلا معلوم است در این معماری کی دوباره کلاینت برگردد و احتیاج به دیتا داشته باشد.
و شما که Connection را در Session نگه می دارید اگر فقط 10 تا کاربر هم زمان داشته باشید مطمئن باشید که برنامه شما با چالش جدی مواجه خواهد شد.
من از آقای mahdi_negahi تعجب می کنم.که با آن همه مقالات زیبا در این مسئله مهم حساسیت کمی نشان می دهند.

گذشته از اینها یک معماری به نام ConnectionManager است که اگر با DesignPattern ها آشنایی داشته باشید ،با الگوی SingleTon طراحی شما و در هر جای برنامه شما اگر کسی کانکشن بخواهد فقط باید به ConnectionManager مراجعه کند.
اگر عمری بود و دوستان نیاز داشتن من می توانیم کد ساده شده این معماری را اینجا قرار دهم و بعد در مورد چند و چون آن باهم بحث کنیم.

به امید موفقیت.

mahdi_negahi
چهارشنبه 19 مهر 1385, 10:26 صبح
من از آقای mahdi_negahi تعجب می کنم.که با آن همه مقالات زیبا در این مسئله مهم حساسیت کمی نشان می دهند.


دوست عزیز نظر لصف شما است ولی من هم از همان اول با صحبتهای این تاپیک مخالف بودم ولی دوستی که این تاپیک را ایجاد کرده تازه وارد ASP.NET شده و هنوز در تضادهایی که در ASP کلاسیک و asp.net است سردرگم است ( ما همه این تضادها را پشت سر گذاشتیم) اگر من میخواستم یک دفعه سراغ معماری چند لایه بروم این دوست ما از هر چی ASP.NET بیزار میشد و سراغ همان تکنولوزی عصر شاه وزوزک میرفت


گذشته از اینها یک معماری به نام ConnectionManager است که اگر با DesignPattern ها آشنایی داشته باشید ،با الگوی SingleTon طراحی شما و در هر جای برنامه شما اگر کسی کانکشن بخواهد فقط باید به ConnectionManager مراجعه کند.
اگر عمری بود و دوستان نیاز داشتن من می توانیم کد ساده شده این معماری را اینجا قرار دهم و بعد در مورد چند و چون آن باهم بحث کنیم.


نیکی و پرسش ما اینجا جمع شدیم که اطلاعات خودمان را shaire کنیم . تا عمر داری این کار را بکن... که اگر عمری نباشد دعایی پشت سرت نیست:چشمک:

koosha system
پنج شنبه 20 مهر 1385, 15:41 عصر
{{دوست عزیز نظر لصف شما است ولی من هم از همان اول با صحبتهای این تاپیک مخالف بودم ولی دوستی که این تاپیک را ایجاد کرده تازه وارد ASP.NET شده و هنوز در تضادهایی که در ASP کلاسیک و asp.net است سردرگم است ( ما همه این تضادها را پشت سر گذاشتیم) اگر من میخواستم یک دفعه سراغ معماری چند لایه بروم این دوست ما از هر چی ASP.NET بیزار میشد و سراغ همان تکنولوزی عصر شاه وزوزک میرفت}}

تایید می کنم.

ASP.net هم معجزه ایست!

mahdi_negahi
پنج شنبه 20 مهر 1385, 18:04 عصر
ASP.net هم معجزه ایست!

هنوز راه طولانی در پیش داری تا به معجزه بودنش پی ببری

SalarSoft
یک شنبه 23 مهر 1385, 12:22 عصر
و شما که Connection را در Session نگه می دارید اگر فقط 10 تا کاربر هم زمان داشته باشید مطمئن باشید که برنامه شما با چالش جدی مواجه خواهد شد.
این نکته در نظر نگرفتید که هر کانکشن در آغاز درخواست پردازش باز شده و در پایان پردازش ها بسته می شود.

برای کل سایت یک کانکشن خواهید که از آغاز درخواست تا پایان اون در اختیار خواهد بود.
خب در این مسئله چون تعداد ارجاعات به دیتا خیلی زیاده برای جلوگیری از این باز بسته شدن ها آن هم در یک درخواست می شه متوسل به این روش شد.
البته این روشنه که این راه حل در هر شرایطی کار ساز نیست!

mahdi_negahi
یک شنبه 23 مهر 1385, 12:27 عصر
این نکته در نظر نگرفتید که هر کانکشن در آغاز درخواست پردازش باز شده و در پایان پردازش ها بسته می شود.

شما ابنو در نظر بگیرید که چند کاربر از چند صفحه که همه این صفحات به اتصال به DB نیاز دارند بازدید میکنند چون شما فقط یک کانکشن تعریف کردید آیا فکر نمی کنید به مشکل برخود کنید

pegasos
دوشنبه 24 مهر 1385, 10:34 صبح
با درود.

می دانید که در ASP.NET وقتی که می خواهید بوسیله DataAdapteer یک DataSet را Fill کنید ،می توانید از یک Connection باز مشترک استفاده کنید، ولی برای DataReader اینطور نیست چون ReadOnly و ForwardOnly است و مستقیم با دیتا بیس در ارتباط است و وقتی یک کانشن را در اختیار او قرار می دهیم دیگر هیچ کس نمی توانید از این کانکشن استفاده کند.

معماری چند لایه در وب هم به صورت DisConnected است یعنی شما در لایه دیتا یک BusinessEntity را [که معمولا یک Typed DataSet است ] از اطلاعات پر می کنید و به لایه های با لا تحویل می دهید. و برای update کردن هم به همین ترتیب BusinessEntity را تحویل می گیرید و تغیرات را بروی بانک اعمال می کنید.

حالا بگذریم از اینکه مضیت های یک DataReader نسبت به DataSet در چه مواردی است و چه حافظه کمی می گیرد و چه سرعت بالایی دارد و ....

می گویم بگذریم برای اینکه در ASP.NET 2.0 ماکروسافت آمد این مشکل را حل کرد و شما با چندDataReader می توانید از یک کانکشن مشترک استفاده کنید.

این همه صغری کبری کردم که این را بگم :
این کلاسی که احتمالا کدش را پایین می بینید یک ConnectionProvider است .یعنی هر جایی که از یک Connection در برنامه تان استفاده کنید باید از این کلاس در خواست کانکشن کنید.
شما نمی توانید از این کلاس یک instance بسازید .
این کلاس یک Indexer داخلی دارد که چنانچه شما برای اولین بار به آن مراجعه کنید.یک کانکشن باز می کند و به شما می دهد.
حالا در عین حال که این کانکشن باز است یک نفر دیگه در خواست کانکشن می کند.نیازی نیست کانکشن جدید بگیرد. همین کانکشن را به او هم تحویل می دهد.و به همین ترتیب...

مسئله ای این است که وقتی کاربران کارشان با کانکشن تمام شد باید به این کلاس بگویند که
کارشان تمام شده و خودشان نباید کانکشن را ببندند.
و ConnectionProvider خودش چنانچه ببیند هیچ کاربری با کانکشن سروکار ندارد خودش کانکشن را برای شما می بندد.

من دوتا متد برای DataReader هم گذاشته ام که عملا هیچ کاری انجام نمی دهند به شما کمک می کنند که شما از یک جا کانکشن حاضر آماده بگیرد و خودتان باید مدیریتش کنید. تا انگیزه ای هم باشد برای مهاجرت به نسخه بعدی دات نت.

من این ver از این کلاس را برای 5 کاربر که همزمان با دیتا سرو کار دارند پیش نهاد می کنم.
برای کاربران بیشتر و سایتهای پر بیننده باید از ConnectionManager MultiThread استفاده کنیم.
که اگرطالب داشته باشد AND عمری باشد AND آقای نگاهی دعای خیری پشت سر ما بکند، حتما در همین مکان قرار می دهم و در باره اش بحث خواهیم کرد.

احتمالا در ذهن دوستان خیلی ابهامات به وجود خواهد آمد من پیشنهاد می کنم قبل از هر گونه پیش داوری فقط ابهاماتشان را بیان کنند.

من پیشاپیش از املاء و انشاء بد فارسی خودم عذر خواهی می کنم.
به امید موفقیت.





using System;
using System.Data.SqlClient;

using IPICS_BASE_V00.Public.Configuration;

namespace IPICS_BASE_V00.CommonDA
{
/// <summary>
/// this class implement the singleton pattern.
/// Manage Connection in all around program.
/// and each object need connection to DB should be get from this class;
/// </summary>
/// <Ver>0.1</Ver>
public class ConnectionManager
{
#region Class Variables

private static int index = 0;
private static SqlConnection cnn = null;

#endregion

#region Class Constructor

private ConnectionManager()
{
}

#endregion

#region Class Methods

/// <summary>
/// get same connection for all request
/// </summary>
/// <example>SqlDataAdapter</example>
/// <returns>a opened connection</returns>
public static SqlConnection GetSharedConnection()
{
index++;
if(null == cnn)
{
cnn = new SqlConnection(IPICSConfiguration.ConnectionString) ;
cnn.Open();
}
return cnn;
}
/// <summary>
/// free opened connection from memory.
/// </summary>
/// <remarks>
/// each user get a connection should be free that connection else the connection will be open..
/// </remarks>
public static void FreeSharedConnection()
{
index--;
if(0 == index)
{ cnn.Close();}
}
/// <summary>
/// get new connection for each request
/// </summary>
/// <example>SqlDataReader</example>
/// <returns>a opened connection</returns>
public static SqlConnection GetSingleConnection()
{
SqlConnection cnn = new SqlConnection(IPICSConfiguration.ConnectionString) ;
cnn.Open();
return cnn;
}
/// <summary>
/// get new connection for each request
/// </summary>
/// <param name="opened">if opened is true get open connection else get close connection</param>
/// <returns>a connection</returns>
public static SqlConnection GetSingleConnection(bool opened)
{
if(opened)
{
SqlConnection cnn = new SqlConnection(IPICSConfiguration.ConnectionString) ;
cnn.Open();
return cnn;
}
else
{
SqlConnection cnn = new SqlConnection(IPICSConfiguration.ConnectionString) ;
return cnn;
}
}
/// <summary>
/// free opened connection from memory.
/// </summary>
/// <remarks>
/// each user get a connection should be free that connection else the connection will be open..
/// </remarks>
public static void FreeSingleConnection(SqlConnection cnn)
{
if(cnn.State == System.Data.ConnectionState.Open)
{ cnn.Close();}
}

#endregion
}
}


و نحوه استفاده در جاهای مختلف :


public dsPerson GetFreshData()
{
//var
//SqlConnection cnn = ConnectionManager.GetConnection();
dsPerson ds = new dsPerson();
SqlDataAdapter da = new SqlDataAdapter("select * from com_person",
ConnectionManager.GetSharedConnection() );
//
da.Fill(ds.com_person);
ConnectionManager.FreeSharedConnection();
return ds;
}



public bool Insert(dsPerson.com_personRow row)
{
bool retVal = false;

cmd = new SqlCommand();

//identify stored procedure
cmd.CommandText = "com_insert_new_person";
cmd.CommandType = CommandType.StoredProcedure;

//identify new parameters
cmd.Parameters.Add("@first_name" ,SqlDbType.NChar ,30);
cmd.Parameters.Add("@last_name" ,SqlDbType.NChar ,30);
cmd.Parameters.Add("@sex" ,SqlDbType.Bit);
cmd.Parameters.Add("@job_title" ,SqlDbType.NChar ,50);
cmd.Parameters.Add("@business_phone_1" ,SqlDbType.Char ,15);
cmd.Parameters.Add("@business_phone_2" ,SqlDbType.Char ,15);
cmd.Parameters.Add("@home_phone" ,SqlDbType.Char ,15);
cmd.Parameters.Add("@mobile" ,SqlDbType.Char ,15);
cmd.Parameters.Add("@business_fax" ,SqlDbType.Char ,15);
cmd.Parameters.Add("@internal_phone" ,SqlDbType.Char ,15);
cmd.Parameters.Add("@e_mail" ,SqlDbType.Char ,50);
cmd.Parameters.Add("@home_address" ,SqlDbType.NChar ,250);
cmd.Parameters.Add("@section_" ,SqlDbType.Int);
cmd.Parameters.Add("@company" ,SqlDbType.Int);
cmd.Parameters.Add("@access_type" ,SqlDbType.Char ,15);
cmd.Parameters.Add("@personally_number" ,SqlDbType.Int);
cmd.Parameters.Add("@e_sign" ,SqlDbType.Char ,15);
cmd.Parameters.Add("@user_name" ,SqlDbType.Char ,15);
cmd.Parameters.Add("@password" ,SqlDbType.Char ,15);
cmd.Parameters.Add("@roles" ,SqlDbType.NVarChar ,250);

//assign value to sql parameters
cmd.Parameters["@first_name"].Value = row.first_name;
cmd.Parameters["@last_name"].Value = row.last_name;
cmd.Parameters["@sex"].Value = row.sex;
cmd.Parameters["@job_title"].Value = row.job_title;
cmd.Parameters["@business_phone_1"].Value = row.business_phone_1;
cmd.Parameters["@business_phone_2"].Value = row.business_phone_2;
cmd.Parameters["@home_phone"].Value = row.home_phone;
cmd.Parameters["@mobile"].Value = row.mobile;
cmd.Parameters["@business_fax"].Value = row.business_fax;
cmd.Parameters["@internal_phone"].Value = row.internal_phone;
cmd.Parameters["@e_mail"].Value = row.e_mail;
cmd.Parameters["@home_address"].Value = row.home_address;
cmd.Parameters["@section_"].Value = row.section_;
cmd.Parameters["@company"].Value = row.company;
cmd.Parameters["@access_type"].Value = row.access_type;
cmd.Parameters["@personally_number"].Value = row.personally_number;
cmd.Parameters["@e_sign"].Value = row.e_sign;
cmd.Parameters["@user_name"].Value = row.user_name;
cmd.Parameters["@password"].Value = row.password;
cmd.Parameters["@roles"].Value = row.roles;

//get new connection from connection manager
cmd.Connection = ConnectionManager.GetConnection();

if(cmd.ExecuteNonQuery() == 1)
{ retVal = true;}
else
{ retVal = false;}

//close connection
ConnectionManager.FreeSharedConnection();

return retVal;
}

SalarSoft
دوشنبه 24 مهر 1385, 15:24 عصر
دقیقا همین کاری که جناب pegasos انجام منظور من است.
ولی با این تفاوت که ایشان مسئله رو خیلی بهتر حل کردند و برای تمامی در خواستها یک کانکشن تعریف کردند در حالی که من برای هر درخواست این کار رو میکردم!

mahdi_negahi
دوشنبه 24 مهر 1385, 16:10 عصر
using IPICS_BASE_V00.Public.Configuration;

ما دعا کردیم ولی این خط خطا میگیرد و public میگه موجود نیست


دقیقا همین کاری که جناب pegasos انجام منظور من است.
ولی با این تفاوت که ایشان مسئله رو خیلی بهتر حل کردند و برای تمامی در خواستها یک کانکشن تعریف کردند در حالی که من برای هر درخواست این کار رو میکردم!

من تا جایی که از صحبتهای شما دستکیرم شد این بود که شما یک کانکشن باز میکردید و آن را در سشن میریختید و به هر جا که نیاز داشتید می دادید

pegasos
سه شنبه 25 مهر 1385, 12:48 عصر
با درود.


ما دعا کردیم ولی این خط خطا میگیرد و public میگه موجود نیست

اول من عذر خواهی می کنم.
بابت اینکه کد هایی که مربوط به تکه های دیگه برنامه من هست در آنجا مونده.

اون خط و یک خط دیگه باید ایراد بگره اگه کلاس را بدون دستکاری بخواهید استفاده کنید.



cnn = new SqlConnection(IPICSConfiguration.ConnectionString) ;


در اینجا کلاس IPICSConfiguration یک Configuration Provider ساده است.که پراپرتی ConnectionString همان کانکشن استرینگ دیتا بیس فعلی را از Config مورد نظر می خواند و برای شما می آورد.

شما طبیعتا باید این خط را به کانکشن استرینگ خودتان تغیر دهید.
اگر بخواهید این کلاس را هم می گذارم.



من تا جایی که از صحبتهای شما دستکیرم شد این بود که شما یک کانکشن باز میکردید و آن را در سشن میریختید و به هر جا که نیاز داشتید می دادید

آقای نگاهی عزیز اینقدر به دوست قدیمی ما آقای سالا گیر نده...
به نظر من هم جناب سالار تا حدی این راه را رفته بودنند...

من منتظر نقد های بیشتری هستم ....

به امید موفقیت.

mahdi_negahi
چهارشنبه 26 مهر 1385, 09:43 صبح
آقای نگاهی عزیز اینقدر به دوست قدیمی ما آقای سالا گیر نده...
به نظر من هم جناب سالار تا حدی این راه را رفته بودنند...

من منتظر نقد های بیشتری هستم ....

به امید موفقیت.


بنده بهآقا سالار ارادت خاص دارم ما اینجا فقط به نقد وبررسی میپردازیم میدانم که دوستان هم همین نظر را دارند و جناب سالار هم اصلا از گیرهای بنده ناراحت نمیشوند، خوب بپردازیم به کارها:

در اینجا کلاس IPICSConfiguration یک Configuration Provider ساده است.که پراپرتی ConnectionString همان کانکشن استرینگ دیتا بیس فعلی را از Config مورد نظر می خواند و برای شما می آورد

یعنی این یک کلاس جدا برای این است که به فایل webconfig دسترسی داشته باشید ؟


اگر بخواهید این کلاس را هم می گذارم.

کار را کی انجام داد؟ ان کس که تمام کرد ( دوستان ادبی لطفا از جمله ناقص بنده اشکال نگیرند)

SalarSoft
جمعه 28 مهر 1385, 16:19 عصر
لطف دارید. به هر حال همانطور که گفتید برای بحث و تبادل نظر و یادگرفتن و یاد دادن اینجا هستیم.
ادامه بحث...

به نظر من برای بستن کانکشن نیازی به شرط نبود:

public static void FreeSingleConnection(SqlConnection cnn)
{
cnn.Close();
}
به این علت که چندین بار نیز میشه کانکشن رو بست

An application can call Close more than one time. No exception is generated.


اما در مورد این کلاس :
به نظر من این کلاس رو میشه تا حدود زیادی کسترش داد.
مورد اول اینکه تمامی کانکشن های ایجاد شده مدیرتی بر روی آنها نیست و تضمینی به بسته شدن آنها نیست و ممکنه به هر علتی مثل خطا ها و استثناها در کد کانکشن بسته نشه.

من تابع FreeAllActiveConnectionsو GetArrayList رو به این کلاس اضافه کردم که FreeAllActiveConnections تمامی کانکشهای درخواستی رو که در یک آرایه درون session ذخیره میشه رو می بنده و در نهایت کانکشن عمومی رو می بنده.
تابع GetArrayList برای اطمینان از وجود شئی ArrayList در session است.
نکته مهم توابع اضافه شده اینه که فراخوانی تابع FreeAllActiveConnections باید درون رویداد EndRequest مربوط به Global.asax باشه تا همیشه این اطمینان باشه که تمامی کانکشن ها بسته است.
به این صورت:


protected void Application_EndRequest(object sender, EventArgs e)
{
IPICS_BASE_V00.CommonDA.ConnectionManager.FreeAllA ctiveConnections();
}

کد های کلاس:



using System.Data.SqlClient;
using System.Collections.Specialized;

//using IPICS_BASE_V00.Public.Configuration;//We don't have it!

namespace IPICS_BASE_V00.CommonDA
{
/// <summary>
/// this class implement the singleton pattern.
/// Manage Connection in all around program.
/// and each object need connection to DB should be get from this class;
/// </summary>
/// <Ver>0.1</Ver>
public class ConnectionManager
{
#region Class Variables

private const string ConnectionsSessionKey = "ConnectionManagerSessionKey";
private static int index = 0;
private static SqlConnection cnn = null;

#endregion

#region Class Constructor

private ConnectionManager()
{
}

#endregion

#region Class Methods

private static ArrayList GetArrayList()
{
ArrayList result=null;
HttpContext context = HttpContext.Current;
if (context != null)
{

result = (ArrayList)context.Session[ConnectionsSessionKey];
if (result == null)
{
result = new ArrayList();
context.Session[ConnectionsSessionKey] = result;
}
}
return result;
}

/// <summary>
/// get same connection for all request
/// </summary>
/// <example>SqlDataAdapter</example>
/// <returns>a opened connection</returns>
public static SqlConnection GetSharedConnection()
{
index++;
if(null == cnn)
{
cnn = new SqlConnection("ConnetcionString!");
cnn.Open();
}
return cnn;
}
/// <summary>
/// free opened connection from memory.
/// </summary>
/// <remarks>
/// each user get a connection should be free that connection else the connection will be open..
/// </remarks>
public static void FreeSharedConnection()
{
index--;
if(0 == index)
{ cnn.Close();}
}
/// <summary>
/// get new connection for each request
/// </summary>
/// <example>SqlDataReader</example>
/// <returns>a opened connection</returns>
public static SqlConnection GetSingleConnection()
{
SqlConnection cnn = new SqlConnection("ConnetcionString!");
cnn.Open();
GetArrayList().Add(cnn);
return cnn;
}
/// <summary>
/// get new connection for each request
/// </summary>
/// <param name="opened">if opened is true get open connection else get close connection</param>
/// <returns>a connection</returns>
public static SqlConnection GetSingleConnection(bool opened)
{
if(opened)
{
SqlConnection cnn = new SqlConnection("ConnetcionString!");
cnn.Open();
return cnn;
}
else
{
SqlConnection cnn = new SqlConnection("ConnetcionString!");
return cnn;
}
}
/// <summary>
/// free opened connection from memory.
/// </summary>
/// <remarks>
/// each user get a connection should be free that connection else the connection will be open..
/// </remarks>
public static void FreeSingleConnection(SqlConnection cnn)
{
FreeSingleConnection(cnn,true);
}

/// <summary>
/// free opened connection from memory.
/// </summary>
/// <param name="remove">Specify that remove connection from requested connections list.</param>
private static void FreeSingleConnection(SqlConnection cnn,bool remove)
{
if(cnn.State == System.Data.ConnectionState.Open)
{ cnn.Close();}

if(remove)
GetArrayList().Remove(cnn);
}

/// <summary>
/// Free all requested connections from this object.
/// </summary>
public static void FreeAllActiveConnections()
{
for(int i=0;i<connections.Count;i++)
FreeSingleConnection((SqlConnection)connections[i],false);
FreeSharedConnection();
GetArrayList().Clear();
}

#endregion
}
}

عفت بزرگه
جمعه 28 مهر 1385, 18:36 عصر
هیچ وقت از یک cn استفاده نکنید . اگر در یک کلاس با یک اسم انرا مرتبا new کنید خوب قابل قبول است اما حالا یک مشگل کلاسی داریم که با هر بار صدا زدن یک cn جدید new می کنه حالا برای اینه از sqltransaction استفاده کنیم نیاز به یک cn داریم . هر بار هم که کلاس یک cn جدید میسازد . پس باید چیکار کرد ؟

pegasos
شنبه 29 مهر 1385, 14:56 عصر
با درود.


به نظر من برای بستن کانکشن نیازی به شرط نبود
کاملاً حق با شماست.


به نظر من این کلاس رو میشه تا حدود زیادی کسترش داد.


بله، من خیلی خیلی از شنیدن این جمله خوشحال شدم .برای اینکه دارم می بینم ما هم به بلوغ و فرهنگ شراکت ،گسترش و توسعه کدباز داریم نزدیک می شویم .



مورد اول اینکه تمامی کانکشن های ایجاد شده مدیرتی بر روی آنها نیست و تضمینی به بسته شدن آنها نیست و ممکنه به هر علتی مثل خطا ها و استثناها در کد کانکشن بسته نشه.




من دوتا متد برای DataReader هم گذاشته ام که عملا هیچ کاری انجام نمی دهند به شما کمک می کنند که شما از یک جا کانکشن حاضر آماده بگیرد و خودتان باید مدیریتش کنید. تا انگیزه ای هم باشد برای مهاجرت به نسخه بعدی دات نت.


ولی کار شما هم کاملا درست است و برای اینکه یک گزینه Optional است فکر نمی کنم به اصل کار دخل و تصرفی داشته باشد.


هیچ وقت از یک cn استفاده نکنید
من متوجه نمی شوم این جمله امری است ،تعجبی است و یا سعالی !!!
می شه بیشتر توضیح بدید.


حالا برای اینه از sqltransaction استفاده کنیم نیاز به یک cn داریم . هر بار هم که کلاس یک cn جدید میسازد
بله این یک مشکل در این معماری است که راه حل خاص خودش را دارد. من نمی توانم جواب شما را بگویم برای اینکه knowledge سازمان قبلی من است.
شما می توانید بیشتر راجع به مشکلتان توضیح دهید. احتمالا دوستان راه حلی پیدا خواهند کرد.

به امید موفقیت.

عفت بزرگه
دوشنبه 01 آبان 1385, 20:37 عصر
دوست من این مشگل با ذخیره یک cn درsession در session start قابل حله . من نمی خواستم از session برای این کار استفاده کنم . می خواستم توی کد کلاسم حلش کنم .

babakj
سه شنبه 09 بهمن 1386, 14:53 عصر
مرسی بحث عالی بود
اتفاقا من هم دنبال همچین چیزی بود که با الگوی Singleton یک کانکشن را مدیریت کند و این کار رو هم انجام داده بود اما مشکل سر مدیریت کانکشن بود که باید با اومدن یک کاربر به صفحه و ایجاد Session برای اون یک کانکشن تا آخر کار بهش بدیم و با از بین رفتن Session اون کانکشن رو هم بگیریم و فکر می کنم برای سایتهای با بیشتر از 10 بازدید کننده همزمان در ثانیه باید از همون روش Multitraeding استفاده بشه که خوشحال می شم در موردش بحث بشه