I fT không đụng độ với bất kỳ giao tác nào đang thực thi thì
2. Phần phân tích hệ thống:
Trên một máy ATM, các thao tác cơ bản được thực hiện: đăng nhập, xem tài khoản, rút tiền, chuyển tiền, thoát khỏi hệ thống.
Khi người sử dụng thực hiện một thao tác, máy ATM sẽ gửi về hệ thống các lệnh theo một định dạng được quy ước trước.
Các định dạng của một giao dịch:
- Đăng nhập:
ATM#: CheckIn(Card#,PIN)
- Thoát:
ATM#: Logout(Acc#)
- Xem tài khoản:
ATM#: Show(Acc#)
- Rút tiền:
ATM#: Withdraw(Acc1#, Amount#)
- Chuyển tiền:
ATM#: Transfer(Acc1#, Amount#, Acc2#)
Khi các giao dịch này được chuyển về “Bộ quản trị giao tác” nó sẽ được phân tích thành một chuỗi các lệnh để gửi về “Bộ lập lịch”.
Các lệnh trong giao dịch cần lưu ý:
Giao dịch “Xem tài khoản”: ATM#: Show(Acc#)
lockR(x) read(x) unlockR(x) commit
Giao dịch “Rút tiền”: ATM#: Withdraw(Acc1#, Amount#) lockW(x) read(x) write(x) unlockW(x) commit
Giao dịch “Chuyển tiền”: ATM#: Transfer(Acc1#, Amount#, Acc2#)
lockW(x) read(x) write(x) lockW(y) read(y) write(y) unlockW(y) unlockW(x) commit * Điểm cần lưu ý:
Trong chuỗi lệnh trên có hai kiểu khóa: lockR(x) và lockW(x), hai kiểu giải phóng khóa tương ứng: unlockR(x) và unlockW(x). Khóa lockR(x) là khóa đọc khi thao tác trên khoản mục x. Khóa lockW(x) là khóa ghi khi thao tác trên khoản mục x. Các lệnh unlockR(x) và unlockW(x) tương ứng với lệnh giải phóng khóa đọc và giải phóng khóa ghi.
Các giao dịch ở đây là các giao dịch thực hiện theo khóa 2 pha (2PL), vì thế cách tổ chức các chuỗi lệnh trong một giao dịch cũng tuân thủ theo nguyên tắc của khóa 2 pha: trong pha tăng trưởng: giao dịch yêu cầu khóa, trong pha thu hồi: chỉ có thể giải phóng khóa mà không được yêu cầu khóa. Bằng cách này,
“Bộ lập lịch” có thể lập lịch biểu khả tuần tự cho các giao dịch 2 pha. Thuật toán xử lý đồng hành:
Ý tưởng:
Như đã trình bày trong phần lý thuyết ở trên, ta thực hiện đồng hành một số lượng giao dịch giới hạn nhằm hạn chế deadlock và tránh tình trạng lan truyền khi quá trình quay lui (rollback) xảy ra. Vì vậy ở đây “Bộ lập lịch” có 3 stack, được sử dụng để nạp chuỗi lệnh của các giao dịch nhận được. Một cơ chế quét lần lượt qua 3 stack, lấy các lệnh trên đỉnh stack để thực hiện. Sau khi được thực hiện xong, lệnh sẽ được remove khỏi stack. Nếu trong quá trình thực thi lệnh, có xuất hiện tranh chấp về khóa ghi, thì giao dịch hiện hành sẽ được rollback và bị hủy. Nếu xuất hiện tranh chấp về khóa đọc, giao dịch hiện hành sẽ được chờ. Khi một stack trở nên rỗng, nó sẽ được nạp chuỗi lệnh của giao
dịch tiếp theo trong hàng đợi. Quá trình này diễn ra liên tục, chỉ kết thúc khi không còn giao dịch nào trong hàng đợi, và tất cả các stack đều rỗng.
Nội dung thuật toán:
Nạp chuỗi lệnh từ hàng đợi với cách sắp xếp FIFO. Mỗi Stack chứa một chuỗi lệnh của một giao dịch
Sub ConcurrentProcessing(); For i=1 to 3 Queue.LoadTransaction() Stack(i) Next idStack=1; Do While idStack<=3 ch := Stack(idStack).GetCommand.Top(); If ch = lockR(x) Then
{Kiểm tra tình trạng khóa của khoản mục x}
If (LockStatus(x) = LockR) or (LockStatus = False) Then
ExecuteCommand ch; Stack(idStack).Remove ch; End If {LockStatus}
End If {If lockR()} If ch = lockW(x) Then
If (LockStatus(x) = False) Then ExecuteCommand ch; Stack(idStack).Remove ch; Else
Rollback Transaction(idStack); End If {LockStatus}
End If {If lockW()}
If ch <> lockR(x) and lockW(x) Then ExecuteCommand ch;
Stack(idStack).Remove ch; End If
If Stack(idStack).IsEmpty = True Then
Queue.LoadTransaction() Stack(idStack); End If
If Stack.AllOfStack.IsEmpty = True Then Exit Do
If idStack = 3 Then idStack = 1 Else idStack= idStack + 1 Loop
End Sub