Transaction ở mức độ cô lập (Isolation Level)
Bài đăng này đã không được cập nhật trong 9 năm
-
Những vấn đề xảy ra khi truy xuất dữ liệu đồng thời
-
Mất dữ liệu cập nhật (Lost update) : Tình trạng này xảy ra khi có nhiều hơn một giao tác cùng thực hiện cập nhật trên 1 đơn vị dữ liệu. Khi đó, tác dụng của giao tác cập nhật thực hiện sau sẽ đè lên tác dụng của thao tác cập nhật trước.
-
Dirty Read : Đọc dữ liệu chưa được chuyển giao (Uncommited Dependence – Dữ liệu chưa được chuyển giao) :
Xảy ra khi một transaction thứ 2 chọn một hàng chưa được cập nhật bởi một transaction khác. Transaction thứ 2 đọc dữ liệu lúc chưa chuyển giao và có thể bị thay đổi bởi transaction đang thực hiện việc cập nhật. Ví dụ : 2 Transaction T3, T4 thực hiện đồng thời, T3 rút $20, T4 gửi thêm $200 nhưng lại hủy bỏ sau đó.
-
Unrepeatable data – Giao tác không thể lặp lại :
Tình trạng này xảy ra khi một giao tác T1 vừa thực hiện xong thao tác đọc trên một đơn vị dữ liệu (nhưng chưa commit) thì giao tác khác (T2) lại thay đổi (ghi) trên đơn vị dữ liệu này. Điều này làm cho lần đọc sau đó của T1 không còn nhìn thấy dữ liệu ban đầu nữa. Ví dụ : Giao tác T5 và T6 cùng thực hiện đồng thời, T5 rút tiền, T6 tính tổng số dư của 3 tài khoản x,y,z. Khi kết thúc 2 giao tác, kết quả T6 không chính xác.
-
Phantom – Bóng ma :
Là tình trạng mà một giao tác đang thao tác trên một tập dữ liệu nhưng giao tác khác lại chèn thêm các dòng dữ liệu vào tập dữ liệu mà giao tác kia quan tâm. 2. Giải pháp xử lý
-
Thực hiện cơ chế Transaction và cơ chế khóa.
-
Trước khi transaction đọc hoặc chỉnh sửa dữ liệu, nó cần được bảo vệ và tránh ảnh hưởng của các transaction khác đang chỉnh sửa cùng dữ liệu.
-
Transaction yêu cầu khóa dữ liệu đang dùng.
-
Có nhiều Mode khóa khác nhau phụ thuộc vào mức độ phụ thuộc dữ liệu của transaction.
-
Sẽ không có transaction nào được cấp khóa nếu gây xung đột với mode khóa đã được cấp trên cùng dữ liệu cho một transaction khác trước đó.
-
Nếu transaction yêu cầu một mode khóa xung đột , DBMS sẽ bắt transaction này dừng lại cho đến khi transaction trước đó được giải phóng.
-
Tất cả các khóa sẽ được giải phóng khi transaction hoàn thành.
-
Hầu hết các DBMS đa người dùng đều tự động thực thi các thủ tục khóa.
-
Lock Manager có nhiệm vụ gán và tạo chính sách khóa cho các transaction.
-
Khi cần phải sử dụng câu lệnh SQL, query processor sẽ xác định tài nguyên nào được truy xuất, loại khóa nào cần dùng, thiết lập mức độ cô lập (Isolation level) cho transaction. Kế đến query processor yêu cầu một khóa phù hợp từ lock manager. Lock Manager sẽ cấp khóa nếu không có xung đột.
- Cấp độ khóa
Có các cấp độ khóa như sau :
-
Mức Database
-
Mức Table
-
Mức Page
-
Mức Row
-
Mức Field
- Các loại khóa
Bất kể mức khóa nào DBMS có thể dùng 2 loại khóa khác nhau :
-
Binary : Có 2 trạng thái Lock(1) và Unlock (0)
-
Shared / Exclusive :
Exclusive Lock : Tồn tại việc truy xuất được dành riêng cho transaction đang khóa đối tượng. Khóa Exclusive phải được dùng khi có thể xảy ra xung đột. Shared Lock : Tồn tại khi các transaction có chung quyền đọc, Shared lock không tạo ra xung đột chừng nào tất cả các transaction đồng thời chỉ đọc. Share Lock được tạo ra khi transaction muốn đọc dữ liệu từ DB và không có Exclusive nào đang nắm giữ trên mục dữ liệu đó. Exclusive lock được tạo ra khi transaction muốn cập nhật mục dữ liệu, hiện thời chưa có khóa nào đang nắm giữ mục dữ liệu. Mỗi khóa có 3 trạng thái : Unlocked, Shared (Read) và Exclusive (Write). 5. Xử lý khóa ở mức độ cô lập
- Read Uncommitted – đọc dữ liệu chưa chuyển giao :
Đặc điểm:
-
Không thiết lập Shared Lock trên những đơn vị dữ liệu cần đọc. Do đó không phải chờ khi đọc dữ liệu (kể cả khi dữ liệu đang bị lock bởi giao tác khác)
-
Vẫn tạo Exclusive Lock trên đơn vị dữ liệu được ghi, Exclusive Lock được giữ cho đến hết giao tác
Ưu điểm
-
Tốc độ xử lý rất nhanh
-
Không cản trở những giao tác khác thực hiện việc cập nhật dữ liệu
Nhược điểm
- Có khả năng xảy ra mọi vấn đề khi xử lý đồng thời :
Dirty Reads Unrepeatable Reads Phantoms Lost Updates Read Commited Đặc điểm
-
Đây là mức độ cô lập mặc định của SQL Server
-
Tạo Shared Lock trên đơn vị dữ liệu được đọc, Shared Lock được giải phóng ngay sau khi đọc xong dữ liệu
-
Tạo Exclusive Lock trên đơn vị dữ liệu được ghi, Exclusive Lock được giữ cho đến hết giao tác
Ưu điểm
-
Giải quyết vấn đề Dirty Reads.
-
Shared Lock được giải phóng ngay, không cần phải giữ cho đến hết giao tác nên không cản trở nhiều đến thao tác cập nhật của các giao tác khác.
Nhược điểm
-
Chưa giải quyết được vấn đề Unrepeatable Reads, Phantoms,Lost Updates
-
Phải chờ nếu đơn vị dữ liệu cần đọc đang được giữ khoá ghi (xlock)
Repeatable Read Đặc điểm
-
Tạo Shared Lock trên đơn vị dữ liệu được đọc và giữ shared lock này đến hết giao tác => Các giao tác khác phải chờ đến khi giao tác này kết thúc nếu muốn cập nhật, thay đổi giá trị trên đơn vị dữ liệu này .
-
(Repeatable Read = Read Committed + Giải quyết Unrepeatable Reads).
-
Tạo Exclusive Lock trên đơn vị dữ liệu được ghi, Exclusive Lock được giữ cho đến hết giao tác.
Ưu điểm
- Giải quyết vấn đề Dirty Reads và Unrepeatable Reads
Nhược điểm
-
Chưa giải quyết được vấn đề Phantoms, do vẫn cho phép insert những dòng dữ liệu thỏa điều kiện thiết lập shared lock
-
Phải chờ nếu đơn vị dữ liệu cần đọc đang được giữ khoá ghi (xlock)
-
Shared lock được giữ đến hết giao tác ==> cản trở việc cập nhật dữ liệu của các giao tác khác
Serializable Đặc điểm
-
Tạo Shared Lock trên đơn vị dữ liệu được đọc và giữ shared lock này đến hết giao tác => Các giao tác khác phải chờ đến khi giao tác này kết thúc nếu muốn cập nhật, thay đổi giá trị trên đơn vị dữ liệu này .
-
Không cho phép Insert những dòng dữ liệu thỏa mãn điều kiện thiết lập Shared Lock (sử dụng Key Range Lock) ==> Serializable = Repeatable Read + Giải quyết Phantoms
-
Tạo Exclusive Lock trên đơn vị dữ liệu được ghi, Exclusive Lock được giữ cho đến hết giao tác.
Ưu điểm
- Giải quyết thêm được vấn đề Phantoms
Nhược điểm
-
Phải chờ nếu đơn vị dữ liệu cần đọc đang được giữ khoá ghi (xlock)
-
Cản trở nhiều đến việc cập nhật dữ liệu của các giao tác khác
Ví dụ xử lý Transaction ở mức độ cô lập (Isolation Level)
Bước 1 :
Tạo CSDL CourseManagement các bảng được mô tả thông qua sơ đồ sau :
Sơ đồ CSDL quan hệ
Bước 2 :
Tạo form có giao diện như sau :
Bước 3 : Viết code để thực thi
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Configuration; using System.Data.SqlClient; using System.Transactions;
namespace IsolationLevelTest { public partial class frmIsolationLeveExample : Form { private SqlConnection conn; private SqlTransaction tran; private string strConn;
public frmIsolationLeveExample()
{
InitializeComponent();
}
private void frmIsolationLeveExample_Load(object sender, EventArgs e)
{
// Lay thong tin chuoi truy cap CSDL trong tep App.Config
strConn = ConfigurationSettings.AppSettings["IsolationConn"].ToString();
conn = new SqlConnection(strConn);
}
private void butStartRead_Click(object sender, EventArgs e)
{
butStartRead.Enabled = false;
System.Data.IsolationLevel IL = System.Data.IsolationLevel.Unspecified;
if (rdoReadCommitted.Checked)
IL = System.Data.IsolationLevel.ReadCommitted;
else if (rdoReadUnCommitted.Checked)
IL = System.Data.IsolationLevel.ReadUncommitted;
else if (rdoRepeatableRead.Checked)
IL = System.Data.IsolationLevel.RepeatableRead;
else if (rdoSerializable.Checked)
IL = System.Data.IsolationLevel.Serializable;
string SqlSelect = “Select * from CourseDates”;
try
{
conn.Open();
tran = conn.BeginTransaction(IL);
SqlCommand cmd = new SqlCommand(SqlSelect, conn, tran);
SqlDataAdapter sda = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
sda.Fill(dt);
dataGrid.DataSource = dt.DefaultView;
butCancel.Enabled = true;
dataGrid.ReadOnly = true;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message,”Transaction Isolation Level”,MessageBoxButtons.OK,
MessageBoxIcon.Error);
conn.Close();
}
}
private void butCancel_Click(object sender, EventArgs e)
{
butCancel.Enabled = false;
dataGrid.ReadOnly = true;
//RoleBack Transaction
tran.Rollback();
conn.Close();
// Bind data with DataGrid = null
dataGrid.DataSource = null;
butStartRead.Enabled = true;
}
private void frmIsolationLeveExample_FormClosing(object sender, FormClosingEventArgs e)
{
//RoleBack Transaction
tran.Rollback();
conn.Close();
}
}
}
All rights reserved