PDA

View Full Version : In use ماندن دیتابیس با وحود استفاده از Connection.Close



reza6384
سه شنبه 30 مهر 1387, 14:47 عصر
سلام دوستان.
سوالم در نگاه اول تکراری به نظر میرسه. اما در تاپیک های قبلی به نتیجه نرسیدم.
یک تاپیک به نام حل مشکل پشتیبان گیری و بازیابی برای همیشه رو SubZero ایجاد کرد و با اون کد تونستم توی VB.NET 2005 برای برنامه ام Backup و Restore درست کردم.

اما مشکل من در VB.Net 2003 هست.

این کدی هست که دارم :

مقدار _BackupFile توسط FileDialog داده میشه.



PublicClass frBackupRestore
Inherits System.Windows.Forms.Form
Dim BackupTice AsString
'-------------------------------------------------
Dim oSQLServer AsNew SQLDMO.SQLServer
DimWithEvents oBackup AsNew SQLDMO.Backup
DimWithEvents oRestore AsNew SQLDMO.Restore
'----------------------------------------------
Dim _INSTANCE AsString = "."
Dim _USER AsString = "sa"
Dim _PWD AsString = ""
Dim _BACKUPFILE AsString = ""
Dim _DATABASE AsString = "Retail"

PrivateSub doBackup()

With oBackup
.Files = _BACKUPFILE
.Database = _DATABASE
.BackupSetName = "MyRetailBackup"
.BackupSetDescription = "Backup from VB.NET application"
.SQLBackup(oSQLServer)
EndWith

MessageBox.Show("Backup Completed Sucessfully", "Message", MessageBoxButtons.OK, MessageBoxIcon.Information)
EndSub


PrivateSub doRestore()

With oRestore
'.Devices = "[NorthwindBackup]"
.Files = _BACKUPFILE
.Database = _DATABASE
.ReplaceDatabase = True
.SQLRestore(oSQLServer)
EndWith
MessageBox.Show("Restore Completed Successfully", "Message", MessageBoxButtons.OK, MessageBoxIcon.Information)
EndSub


PrivateSub frmBackupRestore_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) HandlesMyBase.Load
Data.Connection.Connection.Close()
Data.Connection.Connection.Dispose()
oSQLServer.Connect(".", "sa", "")
EndSub


EndClass


در این برنامه، یک NameSpace هست به نام Data و کانکشن دیتابیس برنامه از طریق
Data.Connection.Connection
قابل دسترسیه. یعنی در فرم Login این کانکشن مقداردهی میشه و open میشه.

من با این کد Backup رو انجام میدم. اما برای Restore کردن error زیر رو نمایش میده :

من نمی دونم چرا با اینکه در FormLoad می نویسم Data.Connection.Connection.Close

و به علاوه وقتی ConnectionState رو قبل از Restore کردن چک میکنم نشون میده که Closed هست ( هر جا چک میکنم میگه Closed هست ) بازهم وقت Restore کردن میگه Database is in use.

در ضمن اگر بنویسم Data.Connection.Connection.Open و بعد هم Connection.State رو چک کنم میگه Closed و واسه همین نمی تونم از Data.Connection.Connection.ChangeDatabase استفاده کنم .

نکته بعدی اینه که اگر فرم ذخیره و بازیابی رو به عنوان StartUp Form انتخاب کنم این کار به درستی انجام میشه.

تقریبا دیگه دارم دیوونه میشم. :عصبانی++::عصبانی++:

__H2__
چهارشنبه 01 آبان 1387, 00:27 صبح
سلام
عزیز دل برادر به اعصابتان مسلط باشید !!
این اتفاق کاملاً بدیهی و واضح است.
ado.net از یک کش داخلی برای connection ها استفاده میکند و در واقع وقتی open میکنیم، اول در این کش میگردد تا یک ارتباط آزاد و خالی پیدا کند و اگر نیافت آنگاه عمل واقعی open را انجام میدهد و با close هم در واقع چیزی بسته نمیشود و فقط connection به کش باز میگردد و برای open بعدی در دسترس خواهد بود.

به همین دلیل زمان اولین connect در برنامه های دات نتی بسیار کند است در حالی که open بعید تا زمانی که در هر لحظه یک ارتباط باز باشد، بسیار سریع خواهد بود.

کد زیر این کش را تخلیه و همه ارتباطات را عملاً میبندد.
System.Data.SqlClient.SqlConnection.ClearAllPools

reza6384
پنج شنبه 02 آبان 1387, 12:17 عصر
خیلی ممنون دوست عزیز. :بوس::بوس::بوس::بوس:
این کانکشن تا کی در CACHE میمونه؟

__H2__
جمعه 03 آبان 1387, 02:58 صبح
سلام
بدون شک تا زمانی که حوزه برنامه جاری تمام نشود کل کش پاک نخواهد شد.
ولی امکان دارد ado.net تا یک درصد مشخصی connection بیکار را قبول کند و اگر تعداد connection های آماده کش شده از یک درصد بیشتر شد (تعداد بلا استفاده نصبت به تعداد کل)، اقدام به بستن ارتباط های اضافه نماید.

البته خودتان هم صراحتاً میتواند این عمل را در connectionstring کنترلر کنید و یا مثل دستور فوق الذکر صراحتاً تمام ارتباطات را واقعاً Close کنید و کش را خالی کنید.

ولی در کل وجودش باعث افزایش بازدهی میشود و فقط در همین موارد نادری که شما با آن مواجه شدید، شاید مشکل ساز شود و نیاز به دخالت مستقیم پیدا کند.

موفق باشید.

reza6384
دوشنبه 06 آبان 1387, 10:00 صبح
سلام.
__H2__ جان، این کد توی 2003 جواب نمیده ، ولی توی 2005 جواب میده. من مشکلم 2003 هستش.

m.yazdian
دوشنبه 06 آبان 1387, 13:47 عصر
من قبلا این مشکل رو داشتم ولی با dispose کردن command و connection این مشکلم حل شده.
امیدوارم که مشکل شما هم حل بشه:تشویق:

__H2__
دوشنبه 06 آبان 1387, 23:40 عصر
سلام

_H2__ جان، این کد توی 2003 جواب نمیده ، ولی توی 2005 جواب میده. من مشکلم 2003 هستش
متاسفم، من الآن اصلاً framework1 را روی سیستمم ندارم.
در این خصوص کمک چندانی نمیتوانم بکنم.

- چک کنید و ببینید کلاسس SqlConnection در framework1 چه متد shared دیگری دارد
در ObjectBrowse یا با نوشتن در سرخط و بدون چیز اضافه ای System.Data.SqlClient.SqlConnection و سپس زدن نقطه باید فقط تمام اعضای shared نمایش داده شود.


- مخزن connection های ado.net را غیر فعال کنید.
در connectionstring مربوطه عبارت Pooling=False را بیاورید. (البته انشا ا... که در 2003 هم جواب دهد!)

موفق باشید.

reza6384
شنبه 11 آبان 1387, 22:24 عصر
سلام H2 جان. آقا ما به دلیل یک سری مشکلات کلا پروژه رو به 2005 آپگرید! کردیم. جالب این بود که حدود 1000 تا warning درست شد که اونها رو Debug کردم، و اینکه حالا ClearAllPools جواب میده. گرچه گفته بودم که مشکلی در 2005 ندارم.
در هر صورت اولا از همکاری و همفکریت صمیمانه ممنون ، ثانیا مطمئن باش که SqlClient.SqlConnection در 2003 اصلا همچین چیزی نداره.