03-10-12, 07:37 AM
كاتب الموضوع : egyption-coder
التحميل الزائد على السيرفر.........بطىء الأضافة و التعديل و الحذف من قاعدة البيانات.........التحميل الزائد على قاعدة البياناتلعل هذه ألأسباب هى ما دفعتنى الى تذكر هذا الموضوع
فمن اسباب التحميل الزائد قيام بعض المبرمجين من تحديث كل صفوف الداتا سيت الى قاعدة البيانات فى كل مرة يتم فيها تعديل احد الصفوف و هذا ليس منطقيا بالطبع و لكن المنطق يدعوا الى تحديث الصفوف التى تم التعديل بها فقط مما يؤدى الى زيادة السرعة و تخفيف التحميل
و لكى نتمكن من ذلك لابد ان نعرف حالات الكائن data row
الحالة added و فيها يتم اضافة الصف الى الداتا تيبل و لكن لم يضاف بعد الى قاعدة البيانات
الحالة deleted و فيها يتم الغاء الصف و لكن لم يتم حذفه بعد من الداتابيز
الحالة modified وفيها يتم تعديل الصف و لكن ليس فى الداتا بيز
الحالة detached و فيها يتم انشاء الصف و لكنه لم يضاف حتى الى الداتا تيبل
الحالة unchanged لا يوجد تغيير فى الصف
و تستخدم هذه الحالات عندما نستدعى الأسلوب update الخاص بالكائن dataAdapter
و هذا الأسلوب هو الذى تستخدمه اداة معالجة البيانات dataForm لكى تحدث قاعدة البيانات
باستخدان الدالة UpdateDataSource
انظر الكود
كود :
Public Function UpdateDataSource(ByVal dataSet As EditProducts.DSProducts) _
As System.Int32
Me.OleDbConnection1.Open()
Dim UpdatedRows As System.Data.DataSet
Dim InsertedRows As System.Data.DataSet
Dim DeletedRows As System.Data.DataSet
Dim AffectedRows As Integer = 0
UpdatedRows = DataSet.GetChanges(System.Data.DataRowState.Modified)
InsertedRows = DataSet.GetChanges(System.Data.DataRowState.Added)
DeletedRows = DataSet.GetChanges(System.Data.DataRowState.Deleted)
Try
If (Not (UpdatedRows) Is Nothing) Then
AffectedRows = OleDbDataAdapter1.Update(UpdatedRows)
AffectedRows = (AffectedRows + OleDbDataAdapter2.Update(UpdatedRows))
AffectedRows = (AffectedRows + OleDbDataAdapter3.Update(UpdatedRows))
End If
If (Not (InsertedRows) Is Nothing) Then
AffectedRows = (AffectedRows + OleDbDataAdapter1.Update(InsertedRows))
AffectedRows = (AffectedRows + OleDbDataAdapter2.Update(InsertedRows))
AffectedRows = (AffectedRows + OleDbDataAdapter3.Update(InsertedRows))
End If
If (Not (DeletedRows) Is Nothing) Then
AffectedRows = (AffectedRows + OleDbDataAdapter1.Update(DeletedRows))
AffectedRows = (AffectedRows + OleDbDataAdapter2.Update(DeletedRows))
AffectedRows = (AffectedRows + OleDbDataAdapter3.Update(DeletedRows))
End If
Catch updateException As System.Exception
Throw updateException
Finally
Me.OleDbConnection1.Close()
End Try
End Function
لقد قامت الدالة بأنشاء ثلاث كائنات داتا سيت جديدة و ملأتها بالصفوف التى تم اضافتها و حذفها و تعديلها على الترتيب ثم قامت بعد ذلك بأستدعاة الأسلوب ابدايت للداتا ادابتر و تحديث قاعدة البيانات من هذه الداتا سيت التى تحتوى على الصفوف المعدلة فقط
هذا جميل جدا ولكن
هناك مشكلة اخرى
ماذا لو كان فى اول صف من الصفوف خطأ مثلا الصف الذى تم تعديله قام احد المستخدمين الأخرين بحذفه من الداتابيز قبل عمل الأبدايت
هنا و بكل اسف سيتم ايقاف كل عملية التحديث
و هذا يسرى على اى صف من الصفوف العشرة الأول و من ثم كل عشرة صفوف فى الداتا سيت
و لكن هناك حل يلجأ اليه بعض المبرمجين و هو ضبط خاصية continueUpdateOnError على true
و هذا حل خطير اذ انك لن تعرف ابدا اذ ما كانت بعض الصفوف تم رفضها ولكن على اى حال فأنت مجبر ان تقبل هذا الأختيار
و الحل المثالى ان تقوم بمعالجة الأمر بالكود
و ذلك بفحص خاصية error لكل صف يتم تحديثه و كذلك فحص خاصية e.staus للعملية الجارية و اذا ما فشلت العملية الخاصة بتحديث الصف فستتحول الخاصية المذكورة الى UpdateStatus.ErrorOccured و يمكنك عندها التعامل مع الخطأ كما تشاء
و الأن مع الكود
اولا كود زر تحديث البيانات العادى و لاحظ انى قد استغنيت عن الداتا سيت الخاصة بالصفوف المعدلة و مازلت لا احدث الا الصفوف المعدلة عن طريق getChanges
كود :
Private Sub UpdateTable(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles bttnUpdate.Click
If Not DsProducts1.GetChanges(DataRowState.Modified) Is Nothing Then _
SqlDataAdapter1.Update(DsProducts1.GetChanges(DataRowState.Modified))
If Not DsProducts1.GetChanges(DataRowState.Added) Is Nothing Then _
SqlDataAdapter1.Update(DsProducts1.GetChanges(DataRowState.Added))
If Not DsProducts1.GetChanges(DataRowState.Deleted) Is Nothing Then _
SqlDataAdapter1.Update(DsProducts1.GetChanges(DataRowState.Deleted))
End Sub
كود :
Handling the DataAdapter’s RowUpdated Event
Private Sub SqlDataAdapter1_RowUpdated(ByVal sender As Object, _
ByVal e As System.Data.SqlClient.SqlRowUpdatedEventArgs) _
Handles SqlDataAdapter1.RowUpdated
Select Case e.Row.RowState
Case DataRowState.Added
Console.Write(“Adding Product ID = “ & _
e.Row.Item(“ProductID”, ataRowVersion.Proposed))
Case DataRowState.Deleted
Console.Write(“Deleting Product ID = “ & _
e.Row.Item(“ProductID”, DataRowVersion.Original))
Case DataRowState.Modified
Console.Write(“Updating Product ID = “ & _
e.Row.Item(“ProductID”, DataRowVersion.Original))
End Select
If e.Status = UpdateStatus.ErrorsOccurred Then
Console.WriteLine(“Failed to update row “)
Console.WriteLine(e.Errors.Message)
e.Row.RejectChanges()
Else
Console.WriteLine(“ Updated successfully”)
e.Row.AcceptChanges()
End If
End Sub
و من ثم نعرض نوع الأجراء(حذف تعديل اضافة)
ثم نفحص e.status و التى يتم ضبطها على UpdateStatus.ErrorOccured اذا اخفقت العملية و عندها نظهر رسالة الخطأ او نتعامل معه
و ارجو فى النهاية ان اكون وفقت فى عرض الموضوع
و الأهم ان يدرك الأخوة اهميته خاصة عندما يصبح حجم البيانات بمئات الألاف او الملايين من الصفوف بينما ما يتم تعديله بضع مئات فقط
و جزاكم الله خيرا