ورود

View Full Version : خطای دوره ای سایت ما روی هاست!



Arash.B
دوشنبه 21 خرداد 1386, 10:17 صبح
سلام به همه ی دوستان.
ما یک سایت با ASP.NET 1.1 و SQL SERVER 2000 طراحی کردیم و روی کامپیوتر خودمون هر چقدر تست می کنیم ظاهرا همه چیز درسته، اما روی هاست هر چند وقت یک بار وقتی سایتو باز می کنیم خطاهای عجیبی میده مثل:
فیلد فلان به جدول فلان تعلق نداره و یا
Dynamic SQL generation for the UpdateCommand is not supported against a SelectCommand that does not return any key column information
که هر دفعه رفرش میکنم یکدوم از این خطاها را نشان می دهد. ولی بعد از اینکه یکی از کارهای زیر را انجام می دم همه چیز بر می گرده به حالت عادی:
تغییر نام dll موجود در شاخه bin و سپس بازگرداندن به نام اصلی ویا
ایجاد تغییر کوچکی در web.config و ذخیره اون ویا آپلود مجدد اون.
که در هر کدوم از حالت های بالا انگار سایت روی iis هاست دوباره رفرش میشه.
حالا حدس ما این بود که ممکنه یک DataReader روی کانکشن ما باز میمونه و برای همیم همه ی DataReaderها رو داخل Try ... Catch گذاشتیم و در قسمت Finally اونا رو بستیم. (چون ما برای کل سایت از یک کانکشن استفاده کردیم و هر موقع لازم بوده اونو بستیم و یا باز کردیم. و هر موقع Nothing بوده New کردیم. و در حالت عادی و حتی پس از تست های فراوان روی کامپیوتر خودمون مشکلی نداشتیم.) ولی مشکل حل نشد.
در ضمن حالا که یکمی تعداد بازدید کننده هامون بالاتر رفته (حدود 30 تا 40 نفر در روز) این مشکل تغریبا هر روز یک یا دوبار پیش میاد.
این بود داستان حسن کچل و وبسایتش!
معضرت میخوام که داستان نوشتم. ممنون میشم اگه وقت بذارین و جواب بدین.:خجالت:

AminSobati
دوشنبه 21 خرداد 1386, 13:21 عصر
دوست عزیزم جدول شما PK داره یا خیر؟ و اگر داره، آیا PK رو در دستور Select قید میکنین؟ ظاهرا نیاز داره که حتما قید بشه

Arash.B
دوشنبه 21 خرداد 1386, 17:16 عصر
دوست عزیزم جدول شما PK داره یا خیر؟ و اگر داره، آیا PK رو در دستور Select قید میکنین؟ ظاهرا نیاز داره که حتما قید بشه

بله امین جان همه ی این مسائل رو رعایت کردم. من در متد Session Start از فایل Global.asax یکی به مقدار ستون Counter از یک جدول در دیتابیس که فقط یک row دارد و PK هم برای آن تعریف شده اضافه کرده و بعد اونو Update میکنم.
در بالا عرض کرده بودم که درحالت عادی روی هاست و مخصوصا روی کامپیوتر خودم هیچ مشکلی با این قضیه نیست. فقط هر چند وقت که این مشکل پیش میاد این خطاها رو دریافت میکنم و به همان طریقی که عرض کردم پس از رفرش سایت در iis هاست این مشکلات بکلی ناپدید میشه.

حالا امین جان به نظر من به این دلیل مشکلات فوق در این قسمت از برنامه خودشو بروز میده که اولین عملیاتی است که (پس از باز کردن سایت) با دیتابیس انجام میشه. در بالا هم عرض کردم وقتی یکی از خطاهای ذکر شده را میده و من دکمه ی رفرش IE رو میزنم اون یکی دیگه رو نماش میده و میگه اصلا Column ی بنام Counter به فلان جدول تعلق نداره!

Behrouz_Rad
دوشنبه 21 خرداد 1386, 18:16 عصر
صحبت های جناب ثباتی در مورد PK صحیح هست اما با توجه به توضیحاتی که دادی، به نظر به ساختار دیتابیس ارتباطی پیدا نمی کنه چون میگی که:

که هر دفعه رفرش میکنم یکدوم از این خطاها را نشان می دهد
و همچنین:

کارهای زیر را انجام می دم همه چیز بر می گرده به حالت عادی:
تغییر نام dll موجود در شاخه bin و سپس بازگرداندن به نام اصلی ویا
ایجاد تغییر کوچکی در web.config و ذخیره اون ویا آپلود مجدد اون.
که در هر کدوم از حالت های بالا انگار سایت روی iis هاست دوباره رفرش میشه.
پس به احتمال زیاد در کدنویسی برای ارتباط با دیتابیس و کلا اشیایی که استفاده می کنی ایرادی وجود داره...
چون پس از کارهایی که در بالا اشاره کردی، سایت شما در IIS ریست میشه و تمامی منابع مرتبط با اون آزاد خواهند شد.
یکی از حدس هایی که درست گفتی میتونه عدم بسته شدن Connection باشه و یا هر دلیل دیگه ای که به کدنویسی اشتباه بر میگرده.
واضح تر اینکه، به این دلیل که سرور منابع محدودی در اختیار شما قرار میده (از جمله حافظه و یا تعداد Connection ها به دیتابیس) و این محدودیت بر روی سیستم در حالت local وجود نداره، پس توضیحات فوق میتونه نمود واقعی بیشتری پیدا کنه.

موفق باشید.

marzban
دوشنبه 21 خرداد 1386, 18:30 عصر
تغییر نام dll موجود در شاخه bin و سپس بازگرداندن به نام اصلی ویا
ایجاد تغییر کوچکی در web.config و ذخیره اون ویا آپلود مجدد اون.

وقتی شما web.config را دوباره upload می کنید کل session ها از اول شروع به کار می کنند.
احتمالا شما در باز و بستن connection های خود دقت نکرده اید.

اگر connection خود را در داخل یک session قرارداده اید این session باید در فایل global.asax
و در بخش session_start قرارداشته باشه مثل کد زیر
Session("con") =your bank address
حال می توانید از این کد در فایل های دیگر استفاده نمایید.
دقت کنید وقتی می خواهید یک connetion را باز کنید بصورت زیر استفاده نمایید
if con.state=ConnectionState.close then con.open
و برای بستن هم از کد زیر
if con.state=ConnectionState.open then con.close

marzban
دوشنبه 21 خرداد 1386, 18:36 عصر
بهتر در برنامه نویسی تحت وب از قراردادن connection داخل web.config استفاده کنی تا global.asax
کد زیر را برای قراردادن connection داخل web.config برات گذاشتم


<connectionStrings>
<add name="MembershipConnectionString" connectionString="DATA SOURCE=localhost;UID=user;PWD=password;DATABASE=te stdb"
providerName="System.Data.SqlClient" />
</connectionStrings>

برای ارتباط داخل برنامه هم از کد زیر میتوانی استفاده کنی


Dim strcon As String
strcon = ConfigurationManager.ConnectionStrings("MembershipConnectionString").ConnectionString

Dim conn2 As New SqlConnection(strcon)

Behrouz_Rad
دوشنبه 21 خرداد 1386, 18:49 عصر
و برای بستن هم از کد زیر
if con.state=ConnectionState.open then con.close
این کد اشتباه بزرگی است!
ما تنها حالت Open و Close نداریم!
اگر Connection مثلا در حالت Fetching یا Broken باشه چی برادر؟
کد فوق رو به شکل زیر اصلاح کن:


If (Con.State <> ConnectionState.Closed) Then Con.Close()


موفق باشید.

marzban
دوشنبه 21 خرداد 1386, 18:51 عصر
ببخشید آقای راد
به نکته خیلی مهمی اشاره کردید
با تشکر
مرزبان

Arash.B
دوشنبه 21 خرداد 1386, 20:03 عصر
با تشکر ازهمه ی دوستان باید عرض کنم من Connection String رو در web.config به صورت زیر تعریف کردم:

<appSettings>
<add key="strConn" value="User ID=MyUser; Data Source=myHostIP; Initial Catalog=MyDBName; password=myPassword;" />
</appSettings>
و البته اینجا بحث طریقه تعریف اون نیست و من برای این نوشتم که کد بعدی رو شرح بدم.
من توی یک ماژول یک تابع به نام openConnection و یک متغیر عمومی به نام con رو تعریف کردم و هر جا لازم بوده که کاری با دیتابیس انجام بشه این تابع رو فراخونی کردم و سپس بعد از اتمام کار با دستور close شیء con عمومی خودمو بستم.
تابع و متغیر مذکور (تعریف شده در ماژول):


Public con As SqlConnection
Public Function OpenConnection(Optional ByVal CloseOldConnection As Boolean = False) As SqlConnection
If IsNothing(con) Then
con = New SqlConnection(ConfigurationSettings.AppSettings("strConn"))
Else
If CloseOldConnection And (con.State <> ConnectionState.Closed) Then
con.Close()
End If
End If
If con.State = ConnectionState.Broken Then con.Close()
If con.State = ConnectionState.Closed Then con.Open()
End Function

که البته باید عرض کنم متغیری که به اون پاس میشه رو بعد از بوجود آمدن این مشکل برای تلاش در جهت رفع اون اضافه کردم و فقط در Session Start وقتی که می خوام اولین بار با دیتابیس کار کنم و به Counter خودم یکی اضافه کنم، مقدار True به اون پاس میدم که وقتی سایتو باز میکنیم اگر con باز باشد اونو ببنده تا در خطوط بعدی از اول باز بشه.
ولی الان که فکر می کنم زیاد منطقی هم نیست چون Session Start برای یوزری که تازه وارد سایت میشه اجرا میشه و یک شیء con مجزا هم برای او به صورت عمومی تعریف میشه.(البته خوشحال میشم که دوستان درباره درستی این تصور هم نظر بدن. البته بدون خارج شدن از بحث اصلی.)


پس به احتمال زیاد در کدنویسی برای ارتباط با دیتابیس و کلا اشیایی که استفاده می کنی ایرادی وجود داره...
چون پس از کارهایی که در بالا اشاره کردی، سایت شما در IIS ریست میشه و تمامی منابع مرتبط با اون آزاد خواهند شد.
یکی از حدس هایی که درست گفتی میتونه عدم بسته شدن Connection باشه و یا هر دلیل دیگه ای که به کدنویسی اشتباه بر میگرده.
واضح تر اینکه، به این دلیل که سرور منابع محدودی در اختیار شما قرار میده (از جمله حافظه و یا تعداد Connection ها به دیتابیس) و این محدودیت بر روی سیستم در حالت local وجود نداره، پس توضیحات فوق میتونه نمود واقعی بیشتری پیدا کنه.

آقای راد با توضیحاتی که من دادم، خوشحال میشم کمی ریزتر به موضوع بپردازید و نظر خودتونو راجع به طریقه ای که کانکشن رو ایجاد، باز و بسته می کنم و همچنین راجع به بکارگیری یک کانکشن عمومی مشترک، بدونم. البته با دید علت یابی مشکلات پیش آمده نه فلسفه ی استفاده از کانکشن که حتما از قبل راجع به اون در این سایت بحث هایی شکل گرفته است.
و همچنین اگه راهی پیشنهاد می کنین برای اطمینان از بسته شدن کانکشن ها و دیگر منابع سراپا گوشیم. مثل: استفاده از Try ... Catch و یا استفاده از Dispose و یا بستن در Session End (هر چند من با احتمال 100 درصد نمیدونم که این Event کی رخ میده. البته حدسایی میزنم و فکر میکنم زمانش رو هم در web.config تعیین کردم. ولی یادم رفته راجع بهش توی MSDN بخونم.)
البته این نکته هم گفتنی است که در موقع وقوع این مشکل من چند باری با Query Analyzer به دیتابیس سایت وصل شدم و لیست کانکشن های موجود را بررسی کردم ولی بیش از سه یا چند کانکشن که معمولا یکی یا دو تا شون در حالت Active بود، نیافتم. که یکی مربوط به همون Query Analayzer و دیگری هم احتمالا موقع چک کردن سایت از طریق IE و برخورد به مشکل بوده!

اینم داستان "حسن کچل و وبسایتش!" قسمت دوم.
بازم از همه معضرت میخوام که داستان نوشتم. فکر میکنم توضیحات کامل تر جلوی انحراف بحث و یا ابهامات احتمالی رو میگیره و باعث میشه بحث زودتر به نتیجه برسه.:خجالت:
آقای مرزبان از شما هم تشکر می کنم که وقت گذاشتین و همچنین از امین عزیز. به این علت روی صحبتم با آقای راد بود که ایشون نزدیکتر به موضوع مشکل من اشاره کردند و من فکر می کنم که تذکراتی که شما دو نفر فرموده بودید رو رعایت کرده بودم.

Behrouz_Rad
دوشنبه 21 خرداد 1386, 21:45 عصر
روالی که برای ایجاد کانکشن نوشتی بسیار بد نوشته شده و به احتمال زیاد به همین دلیل با مشکل مواجه میشی!
حداقل اگر از معماری 3 لایه استفاده نمی کنی، از Data Acess Layer استفاده کن.
بدین منظور می تونی Microsoft Application Blocks for .NET رو داونلود و از اون با اطمینان خاطر به عنوان DAL استفاده کنی. (Search About It)

موفق باشید.

Arash.B
دوشنبه 21 خرداد 1386, 23:31 عصر
با تشکر من میرم مطالعه می کنم و نتیجه رو خبر می دم.
شما درست می فرمایید من از معماری سه لایه استفاده نکردم. البته می دونم که چجوری میشه این کارو کرد ولی بنا به دلایل زیادی که اینجا جای بحثش نیست این کار رو نکردم و یه معماری عجیب و غریب و من درآوردی استفاده کردم که همه چیز روی توی Business Layer نوشتم و وبسایت ما چیزی نیست جز انبوهی از توابع و کلاسها، نکته جالب اینه که تمام صفحات سایت نیز خالی و سفید هستند و حتی template صفحات نیز با کد و در زمان اجرا تولید میشه. و البته از لحاظ سرعت هم کاهش قابل توجهی رو باعث نشده.
همه ی اینا رو گفتم که بیشتر با طرز طراحی این سایت آشنا بشین و ببینید که آیا میشه بدون چند لایه کردن و استفاده از Data Access Layer هم این مشکل رو حل کرد یا نه.
من فهمیدم که کارم تو ایجاد کانکشن ایراد داره و میرم مطالعه میکنم ولی کاش میگفتین چه اشکالی داره و آیا میشه توی همین Business Layer و با تغییری در همین کد درستش کرد یا نه؟
سوالات مختلفی هم که در پست قبلی پرسیدم برای همین بود که بفهم توی همین Business Layer چطوری میشه درستش کرد.:متفکر:
هر چند از پست آقای راد بنظر میرسه که این Microsoft Application Blocks for .NET هم یه سری کلاس یا کد برای همین کار باشه ولی حالا امین جان شما هم یه نظری راجع به چیزایی که مطرح شد بدی خیلی ممنون میشم.
منم میرم Microsoft Application Blocks for .NET رو ببینم چیه.

Behrouz_Rad
سه شنبه 22 خرداد 1386, 08:17 صبح
سوالات مختلفی هم که در پست قبلی پرسیدم برای همین بود که بفهم توی همین Business Layer چطوری میشه درستش کرد.
به کد اعمال متداول با GridView مراجعه کن.