Tăng tốc query (edit)
Giả sử bạn có 20 triệu bản ghi, bạn để khóa là int, bạn cần query tất cả bản ghi có Date là thời gian cách đây 1 tháng.
Để tăng tốc độ truy vấn, nên tạo thêm 1 bảng gồm Date, MaxId với số lượng bản ghi nhỏ hơn 20 triệu.
Khi đó bạn sẽ thực hiện query dựa trên khóa int, where Id > MaxId sẽ nhanh hơn rất nhiều vì truy xuất vảo bảng có ít bản ghi hơn và điều kiện tìm kiếm dựa trên khóa
Concurrency Conflicts in EF Core
https://docs.microsoft.com/en-us/ef/core/saving/concurrency
Concurrency Conflicts in EF6
Implementing Optimistic Concurrency
Các vấn đề liên quan đến việc tranh chấp dữ liệu và cách giải quyết
- Tranh chấp dữ liệu trong SQL Server
- Các cấp độ cô lập trong SQL Server (Isolation Level)
- Các tranh chấp dữ liệu sẽ phát sinh khi cùng lúc có nhiều người dùng đọc và cập nhật cùng dữ liệu giống nhau
- Sử dụng một trong các kỹ thuật sau để quản lý việc nhiều người dùng cùng cập nhật:
- Pessimistic concurrency: Khóa ngay tại thời điểm đọc
- Optimistic concurrency: Khóa tại thời điểm ghi hay cơ chế "First in wins"
- Sử dụng cơ chế "Last in wins"
- Chú ý: ADO.NET cho phép chọn lựa "Last in wins" hoặc "First in wins", mặc định là "First in wins"
Đọc thêm tại đây hoặc bên dưới:
Nội dung
- Tại sao phát sinh vấn đề tranh chấp dữ liệu?
- Các cấp độ cô lập trong SQL Server 2005
- Hướng dẫn sử dụng các cấp độ cô lập trong SQL Server 2005
Giới thiệu
- Trong các ứng dụng nhiều người dùng, tại một thời điểm có nhiều người dùng cùng truy cập và cập nhật dữ liệu giống nhau
- Dẫn đến việc tranh chấp dữ liệu và người phát triển ứng dụng phải đề ra cách giải quyết tranh chấp
- Để giảm thiểu mức độ xung đột một trong những cách giải quyết là sử dụng Transaction
- MS SQL Server 2005 đã hỗ trợ thêm hai cấp độ cô lập mới (ngoài những cấp độ đã hỗ trợ trước)
- Các cấp độ cô lập mới này nhằm làm giảm thiểu thời gian khóa các mẩu tin
1. Tại sao có tranh chấp dữ liệu?
- Các tranh chấp dữ liệu sẽ phát sinh khi cùng lúc có nhiều người dùng đọc và cập nhật cùng dữ liệu giống nhau
- Sử dụng một trong các kỹ thuật sau để quản lý việc nhiều người dùng cùng cập nhật:
- Pessimistic concurrency
- Optimistic concurrency
- "Last in wins"
Pessimistic concurrency
- Khóa ngay tại thời điểm đọc
- Ví dụ: khi user A đọc một mẩu tin thì database engine lập tức khóa ngay mẩu tin này
- Các user khác không thể cập nhật được mà phải chờ
- Khi user A kết thúc cập nhật thì database engine mới mở khóa và các user khác mới có thể cập nhật được
- Đặc điểm
- Bảo đảm tại một thời điểm chỉ cho phép có một cập nhật
- Thích hợp với các ứng dụng có dữ liệu quan trọng cần thay đổi tập trung. Ví dụ các ứng dụng cho phép đặt chổ
- Thời gian chiếm giữ càng ngắn càng tốt
- Không thích hợp với mô hình disconnect vì các kết nối được duy trì đủ để đọc hoặc cập nhật => database engine không thể khóa dữ liệu trong thời gian dài được
Optimistic concurrency
- Khóa tại thời điểm ghi
- Ví dụ: khi các user A và B cùng đọc một mẩu tin thì database engine không khóa mẩu tin này. Nhưng:
- Giả sử user A sửa và ghi thành công (trước user B)
- Sau đó thì đến user B ghi, database engine kiểm tra và phát hiện mẩu tin đã bị sửa trước đó => user B ghi không thành công (First in wins)
- Đặc điểm
- Tại một thời điểm có thể có nhiều người dùng cập nhật
- Thích hợp với các ứng dụng có dữ liệu ít thay đổi tập trung
- Không hao tốn chi phí cho việc khóa dữ liệu
- Thích hợp với mô hình disconnect vì người dùng có thể làm việc lâu dài với dữ liệu đã cache và sau khi kết thúc làm việc thì cập nhật lại CSDL
- ADO.NET cho phép chọn lựa “Last in wins” hoặc “First in wins”
- Mặc định là “First in wins”
2. Các cấp độ cô lập (isolation level)
- Khi tạo Transaction có thể xác định cấp độ cô lập để xác lập ảnh hưởng giữa các Transaction
- Các Transaction cùng truy xuất dữ liệu giống nhau tại cùng thời điểm có thể gây ra các lỗi dị biệt như:
- Dirty read: đọc dữ liệu chưa được Commit
- Transaction thứ nhất (T1) đang cập nhật nhưng chưa Commit
- T2 có thể đọc thấy dữ liệu chưa được Commit của T1
- Non-repeatable read: đọc không nhất quán
- T1 đang đọc dữ liệu đã được Commit
- T2 có thể cập nhật dữ liệu này
- T1 đọc lại và thấy có sự thay đổi
- Phantom read: đọc không bình thường
- T1 đang đọc dữ liệu đã được Commit và dữ liệu được đọc theo điều kiện
- T2 có thể cập nhật dữ liệu liên quan đến điều kiện (mà T2 đang đọc)
- T1 đọc lại và thấy có sự thay đổi
Read Uncommited
- Là cấp độ cô lập thấp nhất trong giao tác
- Các thao tác đọc không yêu cầu khóa dữ liệu => có thể đọc thấy dữ liệu đang bị thay đổi trong các giao tác khác
- Read Uncommited chỉ bảo đảm dữ liệu đọc không bị hỏng vật lý
Read Commited
- Là cấp độ cô lập mặc định trong SQL Server 2005
- Các thao tác đọc sẽ bị treo (dead lock) khi dữ liệu đang bị thay đổi bởi các giao tác khác
- Khắc phục dị biệt Dirty Read
Repeatable Read
- Giao tác sử dụng cấp độ cô lập này sẽ khóa các dữ liệu mà nó đang truy vấn
- Các thao tác khác sẽ không cập nhật được dữ liệu đang bị khóa (dead lock)
- Khắc phục dị biệt Dirty Read và Repeatable Read
Serializable
- Được xem là mức cô lập cao nhất
- Giao tác sử dụng cấp độ cô lập này sẽ khóa các dữ liệu mà nó đang làm việc (có thể khóa toàn bộ table)
- Khắc phục dị biệt Dirty Read, Repeatable Read và Phantom Read
Hai cấp độ cô lập mới
- Read Commited with snapshots: sử dụng row versioning và Optimistic
- Snapshots: giải quyết được các lỗi dị biệt
3. Hướng dẫn sử dụng các cấp độ cô lập
- Các tác nhân ảnh hưởng đến việc chọn cấp độ cô lập
- Data Integrity: ràng buộc dữ liệu => các trường hợp lỗi dị biệt
- Concurrency Conflicts: đụng độ giữa các user
- Performance Overhead: chi phí thực hiện
- Cấp độ cô lập Read Uncommited
- Ứng dụng không yêu cầu dữ liệu đọc được phải chính xác tuyệt đối
- Thao tác dữ liệu phải kết thúc càng nhanh càng tốt
- Cấp độ cô lập Read Commited with Locking
- Ứng dụng không yêu cầu việc truy cập dữ liệu phải diễn ra trong một thời gian dài. Và khi có yêu cầu đọc thì dữ liệu đọc là phải chính xác tuyệt đối
- Thích hợp với việc truy cập dữ liệu tuần tự
- Cấp độ cô lập Read Commited with Snapshots
- Ứng dụng có yêu cầu việc truy cập dữ liệu sẽ diễn ra trong một thời gian dài
- Dữ liệu truy cập nhất quán kể từ khi bắt đầu đọc
- Cấp độ cô lập Repeatable Read
- Ứng dụng có yêu cầu đọc dữ liệu để xem, tính toán và luôn bảo đảm tính nhất quán. Có thể sau khi xem, tính toán thì quyết định cập nhật
- Khi xem và tính toán dữ liệu kết thúc thì các giao tác khác mới được cập nhật dữ liệu
- Cấp độ cô lập Snapshot
- Ứng dụng có yêu cầu đọc dữ liệu để xem, tính toán và luôn bảo đảm tính nhất quán. Có thể sau khi xem, tính toán thì không quyết định cập nhật
- Các giao tác khác vẫn được xem và cập nhật dữ liệu
- Cấp độ cô lập Serializable
- Ứng dụng có yêu cầu đọc dữ liệu để xem, tính toán và luôn bảo đảm tính nhất quán
- Các giao tác khác không đuợc cập nhật dữ liệu
Tính năng nâng cao của ADO.NET
Multiple Active Result Sets (MARS): là việc SQL Server cho phép sử dụng một connection để tạo ra nhiều tập kết quả cùng một lúc
Bổ sung vào chuỗi ConnectionString thuộc tính MultipleActiveResultSets = true
MARS thường được sử dụng với đối tượng SqlCommand và SqlDataReader