Diễn Đàn » Hướng Dẫn Lập trình

Tối ưu hiệu năng của DataAdapter với timestamp

0 trả lời, 460 lượt xem — Trang 1 / 1
Tối ưu hiệu năng của DataAdapter với timestamp
Bạn muốn sử dụng kiểu kiểm tra chặt concurrency nhưng tối ưu hiệu năng DataAdapter.
Thêm một trường timestamp vào bảng, và tạo một lệnh cập nhật tùy biến có sử dụng timestamp này.
Bạn có thể sử dụng CommandBuilder để sinh logic cập nhật cho các bảng trong cơ sở dữ liệu. Tuy nhiên, các lệnh SQL được sinh tự động thường không hiệu quả vì chúng cố so trùng mỗi trường trong một bảng. Khi số lượng cột tăng trong DataTable, số lượng cột trong mệnh đề WHERE của truy vấn cũng sẽ tăng.
Để cải tiến hệ thống này, bạn có thể thêm một trường timestamp đặc biệt vào bảng của mình. Hầu hết các hệ cơ sở dữ liệu đều hỗ trợ kiểu dữ liệu timestamp nào đó, nguồn dữ liệu sẽ cập nhật nó một cách tự động mỗi khi hàng bị thay đổi. Bạn không cần thay đổi cột timestamp bằng tay. Tuy nhiên, bạn có thể xét nó có thay đổi hay không và từ đó xác định một người dùng khác có vừa áp dụng một cập nhật hay không.
Trong một số cơ sở dữ liệu, cột timestamp ghi lại ngày và giờ của lần cập nhật cuối. Đối với SQL Server, cột timestamp là một bộ đếm tăng dần được lưu trữ ở dạng nhị phân và là duy nhất bên trong cơ sở dữ liệu (cũng được xem là cột version của hàng). Một thủ tục tồn trữ SQL Server có thể trả về giá trị timestamp mới nhất từ biến toàn cục @@DBTS.
Điểm thuận lợi của việc sử dụng timestamp là bạn chỉ cần xét một cột để xác định có thay đổi nào đã được thực hiện hay không, điều này sẽ rút ngắn câu lệnh SQL và đơn giản hóa logic tìm kiếm.
Ví dụ dưới đây lặp lại ví dụ đã được trình bày trong mục 14.7. Điểm khác biệt là ví dụ này yêu cầu một cột timestamp có tên là Version. Nếu bất cứ người dùng nào khác thay đổi bất cứ trường nào trong bản ghi, cột Version cũng sẽ thay đổi theo. Trước khi chạy thử nghiệm này, bạn cần thêm cột Version vào bảng Shippers.
Public Module TimestampUpdating    Private ConnectionString As String = "Data Source=localhost;" & _     "Integrated Security=SSPI;Initial Catalog=Northwind"    Public Sub Main()        ' Tạo các đối tượng ADO.NET.        Dim Con As New SqlConnection(ConnectionString)        Dim CmdSelect As New SqlCommand("SELECT * FROM Shippers", Con)        Dim Adapter As New SqlDataAdapter(CmdSelect)        Dim Ds As New DataSet()        ' Đổ dữ liệu vào DataSet.        Try            Con.Open()            Adapter.FillSchema(Ds, SchemaType.Mapped, "Shippers")            Adapter.Fill(Ds, "Shippers")        Catch Err As Exception            Console.WriteLine(Err.ToString())        Finally            Con.Close()        End Try        ' Định nghĩa một câu lệnh cập nhật tùy biến.        Dim UpdateSQL As UpdateSQL = "UPDATE Shippers SET " & _          "CompanyName=@Company, Phone=@Phone WHERE ShipperID=@ID " & _          "AND Version=@Version"        Dim CmdUpdate As New SqlCommand(UpdateSQL, Con)        ' Ánh xạ các giá trị thông số đến các trường trong DataSet.        CmdUpdate.Parameters.Add("@Company", SqlDbType.VarChar, 40, _          "CompanyName")        CmdUpdate.Parameters.Add("@Phone", SqlDbType.VarChar, 24, _          "Phone")        Dim Param As SqlParameter = CmdUpdate.Parameters.Add("@ID", _          SqlDbType.Int, Nothing, "ShipperID")        Param.SourceVersion = DataRowVersion.Original        Param = CmdUpdate.Parameters.Add("@Version", _          SqlDbType.Timestamp, Nothing, "Version")        Adapter.UpdateCommand = CmdUpdate        ' Áp dụng một thay đổi đối với hàng có ShipperID=1        ' ("Speedy Express"), sử dụng một bản sao DataSet.        Dim DuplicateDs As DataSet = Ds.Copy()        Dim Row As DataRow = DuplicateDs.Tables(0).Rows.Find(1)        Row("CompanyName") = "Deluxe Express"        Try            Con.Open()            Adapter.Update(DuplicateDs, "Shippers")            Console.WriteLine("Successfully applied change from " & _              "DuplicateDs.")        Catch Err As Exception            Console.WriteLine(Err.ToString())        Finally            Con.Close()        End Try        ' Bây giờ áp dụng một thay đổi mâu thuẫn, sử dụng DataSet gốc.        ' Điều này giả lập vấn đề concurrency, vì các giá trị gốc        ' trong hàng không giống với thông tin trong cơ sở dữ liệu.        Row = Ds.Tables(0).Rows.Find(1)        Row("CompanyName") = "Super Deluxe Express"        Try            Con.Open()            ' Thất bại vì timestamp không trùng khớp.            Adapter.Update(Ds, "Shippers")            Console.WriteLine("Successfully applied conflicting change")        Catch Err As Exception            Console.WriteLine("Attempt to apply conflicting change failed.")        Finally            Con.Close()        End Try        Console.ReadLine()    End SubEnd Module

Khi tạo một câu lệnh cập nhật tùy biến với timestamp, bạn nên viết mệnh đề WHERE sao cho nó thực hiện so trùng cả timestamp và một trường duy nhất nào đó. Về mặt kỹ thuật, trường timestamp là duy nhất trong cơ sở dữ liệu, và nó có thể được sử dụng để so trùng một hàng duy nhất. Tuy nhiên, khóa chính sẽ khiến thao tác tìm kiếm thực hiện nhanh hơn vì cột khóa chính hầu như luôn có một chỉ mục. Bạn đừng nên tạo chỉ mục trên một giá trị timestamp vì nó thay đổi thường xuyên.
 
 Trích từ "các giải pháp lập trình VB.Net (tập 2)"
Đăng nhập để trả lời
0