Tính nguyên tử

Một phần của tài liệu Quản lý giao tác trong CSDL quan hệ và phân tán (Trang 89)

Xét lại ví dụ về chương trình chuyển tiền từ tài khoản này sang tài khoản kia ở trên. Giả sử có một hư hỏng nào đó xẩy ra ở sau dòng 14. Hư hỏng có thể là do một sự cố máy tính hoặc mạng.... Khi đó cơ sở dữ liệu được đặt ở trạng thái tiền đã được chuyển vào tài khoản thứ hai nhưng chưa được trừ đi khỏi tài khoản thứ nhất, như vậy sẽ gây ra việc ngân hàng bị mất tiền!

Để giải quyết điều đó, SQL đưa vào các lệnh START TRANSACTION, COMMIT, ROLLBACK và đặt vào các vị trí như đã nói ở trên. Nếu có một hư hỏng xẩy ra sau dòng 14, giao tác vẫn chưa đi đến lệnh SQL COMMIT,

nghĩa là những thay đổi của cơ sở dữ liệu vẫn chưa được lưu giữ. Như vậy kết quả của lệnh UPDATE thứ nhất (chuyển tiền) vẫn chưa được lưu vào cơ sở dữ liệu. Do giao tác bị hỏng nên hệ thống sẽ căn cứ vào thông tin trong file log mà khôi phục lại giá trị cho tài khoản thứ hai, việc mất tiền là không xảy ra.

Giao tác chỉ đọc

Chúng ta đã biết, các giao tác chỉ đọc không làm thay đổi trạng thái của cơ sở dữ liệu và do đó chúng có thể được thực hiện song song với các giao tác khác. Xét ví dụ cụ thể sau:

Giả sử chúng ta muốn viết một hàm đọc các dữ liệu để xác định xem một chỗ (trên máy bay) có rỗi hay không. Hàm này sẽ hoạt động giống như từ dòng 1 đến dòng 11 của hàm chooseSeat( ). Ta có thể thực hiện nhiều lần gọi hàm này cùng một lúc mà không sợ làm hại đến cơ sở dữ liệu. Như vậy ta cần báo với hệ thống SQL rằng đây là một giao tác chỉ đọc. SQL cho phép chúng ta báo với hệ thống một giao tác chỉ đọc bằng lệnh:

SET TRANSACTION READ ONLY;

Lệnh này phải được thực hiện trước khi giao tác bắt đầu. Ví dụ, nếu hàm của chúng ta bao gồm các dòng từ dòng 1 đến dòng 11 của chương trình chọn chỗ thì ta có thể khai báo nó là chỉ đọc bằng cách đặt

EXEC SQL SET TRANSACTION READ ONLY; ngay trước dòng 9, nơi bắt đầu giao tác.

Vấn đề Dirty Read

Dữ liệu rác là các dữ liệu được ghi bằng một giao tác nhưng còn chưa được lưu giữ (commited). Việc đọc một dữ liệu rác gọi là dirty read. Dirty read có thể gây ra các sai sót nghiêm trọng mà cũng có thể không có mấy ý nghĩa. Xét hai trường hợp sau đây:

Dirty read không gây nguy hiểm

Giả sử ta có một thay đổi trên hàm chooseSeat( ) như sau:

1.Chúng ta tìm thấy một chỗ rỗi và đăng ký nó bằng cách làm cho occ trở thành TRUE đối với chỗ đó.

2.Hỏi khách hàng có đồng ý với chỗ đó không. Nếu khách hàng đồng ý, ta giữ lại (COMMIT). Nếu không, ta giải phóng chỗ bằng cách làm cho occ thành FALSE và lặp lại bước 1 để lấy chỗ khác.

Nếu hai giao tác đang thực hiện thuật toán tại cùng một thời điểm, một giao tác có thể đăng ký chỗ S (ở bước 1) và sau đó giải phóng nó do khách hàng không đồng ý. Nếu giao tác thứ hai thực hiện bước 1 tại thời điểm khi chỗ S được đánh dấu là đã đăng ký (nhưng chưa commit), khách hàng ứng với giao tác này sẽ không được lựa chọn để lấy chỗ S. Lý do là do giao tác thứ hai đã đọc dữ liệu rác (giá trị occ). Tuy có sai sót như vậy nhưng nó không gây nguy hiểm lắm, bởi vì khách hàng thứ hai có thể không chọn được chỗ S nhưng khi chạy lại giao tác lần sau chỗ đó vẫn được bán. Trong những trường hợp như vậy, việc cài đặt hàm chooseSeat như vậy cho phép đọc dữ liệu rác. Điều đó làm giảm thời gian xử lý trung bình đối với các yêu cầu mua vé

SQL cho phép chúng ta chỉ ra rằng các dirty read là chấp nhận được với một giao tác cho trước bằng cách sử dụng cặp lệnh:

1. SET TRANSACTION READ WRITE;

2. ISOLATION LEVEL READ UNCOMMITED;

Dòng lệnh 1 có nghĩa là giao tác có thể ghi dữ liệu. Dòng lệnh 2 khi bó rằng giao tác có thể chạy với “isolation level” read-uncommited, nghĩa là giao tác được cho phép thực hiện các dirty read.

Dirty read có thể gây nguy hiểm

Giả sử chúng ta thay thế việc chuyển khoản trong chương trình transfer() ở trên bằng một chương trình thực hiện các dãy bước như sau:

1. Thêm tiền vào tài khoản thứ hai 2. Kiểm tra tài khoản thứ nhất:

a) Nếu không có đủ tiền: lấy tiền ra khỏi tài khoản thứ hai và dừng b) Nếu có đủ tiền: trừ số tiền ra khỏi tài khoản thứ nhất và dừng. Nếu chương trình này được thực hiện một cách có thứ tự thì kết quả của nó cũng hoàn toàn giống như chương trình transfer( ) ở trên. Trong trường hợp thực hiện đan xen có thể dẫn đến nguy hiểm (cho kết quả không mong đợi). Giả sử giao tác cho phép dirty-read và ta có tình huống sau: Có ba tài khoản A1, A2, A3 với số tiền 100$, 200$ và 300$ tương ứng. Giả sử rằng giao tác T1 thực hiện chương trình P để chuyển 150$ từ A1 đến A2. Cùng một thời gian, giao tác T2 chạy chương trình P để chuyển 250$ từ A2 đến A3. Có khả năng xẩy ra các sự kiện sau:

1.T2 thực hiện bước 1 và them 250$ vào A3 và bây giờ A3 có 550$ 2.T1 thực hiện bước 1 và thêm 150$ vào A2 và bây giờ A2 có 350$ 3.T2 thực hiện kiểm tra của bước 2 và thấy rằng A2 có đủ tiền (350$)

để cho phép chuyển 250$ từ A2 sang A3.

4.T1 thực hiện kiểm tra của bước 2 và thấy rằng T1 không có đủ tiền (100$) để cho phép chuyển 150$ từ A1 sang A2.

5.T2 thực hiện tiếp bước 2, nó trừ đi 250$ từ A2 và bây giờ A2 có 100$ và kết thúc

6.T1 thực hiện tiếp bước 2, nó trừ đi 150% từ A2 và bây giờ A2 có – 50$ và kết thúc.

Tổng số tiền không thay đổi, trong ba tài khoả vẫn có 600$ nhưng do T2 đọc dữ liệu bẩn ở bước 3 trong 6 bước trên, ta không bảo vệ được việc một tài khoản trở nên âm (vi phạm quy chế của ngân hàng).

Kết quả thực hiện đồng thời hai giao tác T1, T2 như trên dẫn đến sai lầm nghiêm trọng. Để ngăn ngừa những trường hợp như vậy, ta phải sử dụng các công cụ của SQL để làm cho các giao tác phải thực hiện theo thứ tự.

Ngoài việc SQL có thể chỉ ra một giao tác là có thể dirty read, nó còn cho phép chỉ ra một giao tác không được dirty read bằng cách dùng lệnh

SET TRANSACTION ISOLATION LEVEL READ COMMITED và chỉ ra một giao tác không được đọc các bộ “ảo - phantom” bằng cách dùng lệnh

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ Các read uncommited, read commited, reapeatable read và xếp hàng có thứ tự được gọi là các mức cô lập của các giao tác trong SQL.

KẾT LUẬN

Trong luận văn này, tôi đã trình bày khái niệm về giao tác, tầm quan trọng của việc quản lý các giao tác đồng thời và các loại lịch biểu tương ứng với các giao tác và chỉ ra lịch biểu nào có thể khôi phục được các giao tác mỗi khi giao tác bị hỏng.

Việc quản lý các giao tác được thực hiện bằng các thuật toán điều khiển đồng thời và đảm bảo sự loại trừ lẫn nhau trong việc truy cập các mục dữ liệu hoặc sự đồng bộ của các giao tác nhằm đảm bảo việc truy cập dữ liệu đúng đắn và an toàn. Các thuật toán này được trình bày tương đối đầy đủ ở chương 2.

Trong chương 2, tôi trình bày các kỹ thuật được cụ thể hóa trong ngôn ngữ SQL. Các thực nghiệm với hệ thống cho thấy hệ thống đáp ứng các yêu cầu, tính năng được đặt ra. Hoạt động và khả năng phục hồi dữ liệu của hệ thống tốt. Mặc dù việc đáp ứng các tiêu chí bảo mật, khả năng bảo trì là rất khó hoặc có thể nói là không thể đo kiểm một cách đáng thuyết phục, với những hiểu biết hiện tại, hệ thống vẫn được coi là hoàn toàn đáp ứng các yêu cầu đặt ra. Trong phạm vi nào đó, việc triển khai phải được giới hạn ở các tính năng tối thiểu vì sẽ là không khả thi hoặc vô nghĩa để bao trùm tất cả các tùy chọn có thể trong phạm vi luận văn này

Trong quá trình hoàn thành đề tài, tôi nhận thấy rằng việc nghiên cứu lý thuyết về quản lý giao tác và thực hành các kỹ thuật quản lý giao tác với các ngôn ngữ lập trình cụ thể là một việc có ý nghĩa, một lĩnh vực nghiên cứu rộng lớn và có nhiều triển vọng. Nó đảm bảo sự đúng đắn cho cơ sở dữ liệu khi truy cập đến nó để lấy thông tin hoặc cập nhật thông tin. Ngoài ra nó còn cho các kiến thức về điều khiển các tiến trình đồng thời của hệ điều hành.

Mặc dù đã tìm hiểu được một số kiến thức nhất định nhưng tôi thấy để nắm vững được các kỹ thuật điều khiển giao tác là một việc khó khăn, nó yêu cầu có nhiều kiến thức về hệ điều hành và cơ sở dữ liệu. Tuy nhiên, đây là một đề tài thú vị và có nhiều ứng dụng quan trọng trong việc khai thác cơ sở dữ liệu. Trong tương lai, tôi đi sâu vào nghiên cứu hơn nữa về vấn đề này và cố gắng viết các đoạn chương trình thực nghiệm.

Do thời gian cũng như trình độ còn hạn chế, chắc chắn luận văn còn mắc lỗi trong kiến thức và trong trình bày. Tôi chân thành mong các thầy, các bạn tận tình chỉ rõ để tôi sửa chữa trong quá trình nghiên cứu tiếp theo.

TÀI LIỆU THAM KHẢO

[1] Navart and Elmasry, “Foundermental of Database systems”, chapter 19 and chapter 20.

[2] Philip A. Bernstein, Vassos Hadzilacos, Nathan Goodman (1987) “Concurrency control and Recovery In Database Systems

[3] Raghu Ramakrishnan, Johnnes Gehrke (1987) “Database Management Systems (2nd Ed)”.

[4] Rasmus Pagh (2007), Lecture 7: Concurrency control, Database Tuning, Spring.

[5] Kjell Orsborn, DATABASE TECHNOLOGY - 1MB025 Fall 2005

[6] Valentina Tamma, Transaction Management, Connolly & Begg. Chapter 19. Third edition.

[7] http://www.csc.liv.ac.uk/~dirk/Comp332/COMP332-transaction-notes.pdf [8] http://en.wikipedia.org/wiki/ACID

[9] http://www.vocw.edu.vn/content/m10677/latest/

[10] Jame Cook University, “Advanced Database Management (CP3020)”, Chapter 20 - Concurrency Control Techniques

Một phần của tài liệu Quản lý giao tác trong CSDL quan hệ và phân tán (Trang 89)

Tải bản đầy đủ (PDF)

(96 trang)