Đăng bởi: daoquanghuynh | 22/01/2010

Lock dữ liệu trong Oracle

Để ngăn chặn sự xung đột có thể xảy ra khi có nhiều transaction cùng truy cập vào một nguồn tài nguyên (table, row, bộ nhớ,…), Oracle đặt ra các cơ chế lock dữ liệu.

Theo mặc định thì Oracle sẽ tự động lock dữ liệu khi cần thiết mà không cần tới sự can thiệp của người dùng, gọi là lock ngầm định (implicit locking). Và khi tự động lock dữ liệu, Oracle luôn chọn cấp độ lock thấp nhất có thể được.

Bên cạnh đó, Oracle cũng cung cấp các câu lệnh để người dùng có thể tự lock dữ liệu khi cần, gọi là lock xác định (explicit locking).

1.Các chế độ lock

Oracle cung cấp hai chế độ lock như sau:

  • Exclusive lock (lock độc quyền): Chế độ lock này không cho phép các transaction khác thay đổi trên cùng một tài nguyên. Các transaction khác muốn thay đổi dữ liệu thì phải chờ cho tới khi dữ liệu được unlock. Khi một transaction đã lock độc quyền trên tài nguyên thì các transtaction khác không thể lock trên tài nguyên đó.
  • Share lock (lock chia sẻ): Chế độ lock này không cho phép các transaction khác tiến hành lock độc quyền nhưng vẫn cho phép chúng cùng lock chia sẻ trên một tài nguyên.

Ví dụ: Khi một transaction tiến hành sửa dòng có mã là 100 của bảng employees:

  • Dòng có mã 100 sẽ bị exclusive lock nên các transaction khác sẽ không thể chỉnh sửa dòng này.
  • Bảng employees sẽ bị share lock nên các transaction khác sẽ không thể cập nhật cấu trúc của nó (vì để thay đổi cấu trúc bảng thì cần phải tiến hành exclusive lock). Tuy nhiên các transaction khác vẫn có thể thay đổi các dòng khác của bảng employees (khi đó bảng employees sẽ bị nhiều share lock).

2.Thời hạn lock

Oracle không cung cấp lệnh unlock tài nguyên. Do đó, tài nguyên sẽ bị lock cho tới khi transaction lock nó kết thúc (commit hoặc roll back). Và chỉ sau khi transaction kết thúc thì những gì nó thay đổi trên dữ liệu mới được các transaction khác nhìn thấy.

Nếu tài nguyên bị lock sau một save point thì khi transaction được roll back về save point đó, tài nguyên trên sẽ được unlock. Tuy nhiên những transaction đang chờ tài nguyên này vẫn chưa được quyền chỉnh sửa nó mà phải chờ cho transaction kia (transaction đã lock tài nguyên) kết thúc hoàn toàn.

3.Chuyển đổi lock và leo thang lock

3.1.Chuyển đổi lock

Chuyển đổi lock là đưa lock ở mức thấp lên lock ở mức cao hơn.
Oracle sẽ chuyển đổi lock khi cần thiết. Ví dụ khi ta tiến hành lệnh SELECT với tùy chọn FOR UPDATE, Oracle sẽ lock các dòng bị ảnh hưởng ở mức độc quyền và lock bảng ở mức row share. Nếu sau đó ta tiếp tục cập nhật các dòng đã lock thì bảng sẽ được chuyển sang lock ở mức cao hơn là row exclusive.

Với các dòng được thêm, xóa, sửa thì Oracle sẽ lock chúng ở mức độc quyền. Đó là mức lock cao nhất nên không cần chuyển đổi nữa.

3.2.Leo thang lock

Một số hệ quản trị CSDL thường tiến hành leo thang lock khi có quá nhiều lock được thực hiện. Ví dụ: Khi ta lock nhiều dòng trong một bảng thì hệ quản trị CSDL sẽ tiến hành lock ở mức bảng. Cách này giúp giảm số lock phải quản lý nhưng sẽ khiến cho một số tài nguyên bị lock một cách không cần thiết.

Oracle không bao giờ sử dụng leo thang lock bởi vì cách này sẽ làm tăng khả năng xảy ra dead lock.

4.Dead lock

Dead lock xảy ra khi nhiều user cùng chờ các tài nguyên bị lock của nhau.
Ví dụ:

  • Thời điểm T1: user A tiến hành lệnh cập nhật dòng có mã 100 của bảng employees => dòng 100 đó bị lock độc quyền.
  • Thời điểm T2: user B tiến hành lệnh cập nhật dòng có mã 200 của bảng employees => dòng 200 đó bị lock độc quyền.
  • Thời điểm T3: user B tiến hành lệnh cập nhật dòng có mã 100 của bảng employees. Do dòng 100 đang bị lock độc quyền bởi user A nên user B phải chờ user A.
  • Thời điểm T4: user A tiến hành lệnh cập nhật dòng có mã 200 của bảng employees. Do dòng 200 đó đang bị lock độc quyền bởi user B nên user A phải chờ user B.
  • Như vậy hai user A và B sẽ phải chờ nhau mà không làm được gì khác => lock xảy ra.

Oracle tự phát hiện dead lock và sẽ rollback một trong các transaction bị dead lock, từ đó hủy bỏ các lock gây xung đột.

Để tránh dead lock, ta có thể đặt ra quy ước về thứ tự làm việc để luôn tiến hành lock các tài nguyên theo một thứ tự nào đó.

5.Các loại lock

Có các loại lock chính như sau:

  • DML lock (lock dữ liệu): có chức năng bảo vệ dữ liệu, ví dụ như lock toàn bộ dữ liệu của một bảng, lock một số dòng trong bảng,…
  • DDL lock (lock cấu trúc): có chức năng bảo vệ cấu trúc của các đối tượng trong schema, ví dụ như bảng, view,…
  • Latch (chốt) và internal lock (lock nội): bảo vệ cấu trúc nội bộ của CSDL. ví dụ như các datafile. Dạng lock này được tiến hành hoàn toàn tự động.

5.1.DML lock

DML lock có chức năng đảm bảo sự nhất quán của dữ liệu trong môi trường đa người dùng. Nói cách khác, DML lock bảo đảm rằng mỗi dòng chỉ có thể được cập nhật bởi tối đa một transaction trong một thời điểm. Bên cạnh đó, DML lock còn ngăn chặn sự thay đổi về cấu trúc của một bảng từ transaction khác nếu có một transaction đang cập nhật dòng trong bảng đó.

Ví dụ: Khi transaction A đang cập nhật dòng 100 của bảng employees thì transaction B phải chờ transaction A kết thúc mới được phép cập nhật trên dòng đó.

Lock dòng (row lock – TX)

Loại DML lock duy nhất mà Oracle tự động tạo ra là lock ở mức dòng. Không có giới hạn về số dòng được lock trong một transaction, và Oracle không bao giờ tiến hành leo thang lock.
Sự kết hợp của cơ chế quản lý đồng thời đa phiên bản với lock ở mức dòng cho phép:

  • Transaction đọc không cần phải chờ transaction ghi, ngay cả khi chúng cùng truy cập trên một dòng
  • Transaction ghi không cần phải chờ transaction đọc, ngay cả khi chúng cùng truy cập trên một dòng (trừ khi transaction đọc dùng thêm tùy chọn FOR UPDATE khi truy vấn dữ liệu).
  • Các transaction ghi chỉ phải chờ nhau khi chúng cần ghi trên cùng một dòng.

Một transaction sẽ dùng DML lock độc quyền khi nó chạy các câu lệnh DML (INSERT, UPDATE, DELETE) và lệnh SELECT với tùy chọn FOR UPDATE. Mà một dòng không thể bị hai lock độc quyền trong một thời điểm, do đó không thể có hai lệnh DML thực thi cùng lúc trên một dòng.

Khi một dòng đang bị lock độc quyền bởi một transaction, các transaction khác không thể chỉnh sửa dòng đó cho đến khi transaction đang lock được kết thúc (commit hoặc roll back). Tuy nhiên, có một ngoại lệ là nếu transaction bị kết thúc một cách bất bình thường (ví dụ như máy client đang chạy transaction đó bị cúp điện) thì các dòng sẽ được unlock trước khi transaction được phục hồi.

Nếu một transaction lock một dòng, nó cũng tiến hành lock bảng chứa dòng đó. Việc lock bảng là để ngăn chặn các transaction khác thay đổi cấu trúc (hoặc xóa) bảng.

Lock bảng (Table lock – TM)

Bảng sẽ bị lock nếu transaction tiến hành các lệnh DML, lệnh SELECT với tùy chọn FOR UPDATE hoặc lệnh LOCK TABLE trên nó. Các lệnh DML cần phải lock bảng để bản đảm sự truy cập dữ liệu và ngăn chặn sự thay đổi trên cấu trúc bảng (lệnh DDL) từ transaction khác.

Lệnh DDL sẽ tiến hành lock bảng ở mức độc quyền trước khi chạy. Mà các loại lock bảng sẽ ngăn chặn sự lock bảng độc quyền, do đó lệnh DDL sẽ không thể chạy được trên bảng đang bị lock.

Có các chế độ lock bảng như sau: row share (chia sẻ dòng – RS), row exclusive (độc quyền dòng – RX), share (chia sẻ – S), share row exclusive (chia sẻ dòng độc quyền – SRX) và exclusive (độc quyền – X).

Câu lệnh SQL Chế độ lock Các chế độ lock được phép
S RX S SRX X
SELECT … Y Y Y Y Y
INSERT … RX Y Y N N N
UPDATE … RX Y* Y* N N N
DELETE … RX Y* Y* N N N
SELECT … FOR UPDATE RS Y* Y* Y* Y* N
LOCK TABLE table IN ROW SHARE MODE RS Y Y Y Y N
LOCK TABLE table IN ROW EXCLUSIVE MODE RX Y Y N N N
LOCK TABLE table IN SHARE MODE S Y N Y N N
LOCK TABLE table IN SHARE ROW EXCLUSIVE MODE SRX Y N N N N
LOCK TABLE table IN EXCLUSIVE MODE X N N N N N

Chú thích:

  • RS: Row share
  • RX: Row exclusive
  • S: Share
  • SRX: Rhare Row exclusive
  • X: Exclusive
  • *: Nếu không có xung đột thì sẽ lock. Ngược lại thì phải chờ.

Cơ chế lock mặc định cho câu truy vấn

Câu truy vấn là câu lệnh SELECT không có tùy chọn FOR UPDATE.. Trong Oracle, câu truy vấn không tạo ra lock và do đó không chịu ảnh hưởng bởi lock. Do đó, một transaction có thể truy vấn dữ liệu trong khi transaction khác đang tiến hành sửa đổi trên cùng dữ liệu đó.

Cơ chế lock mặc định cho lệnh DML và SELECT với tùy chọn FOR UPDATE

Khi thực thi lệnh DML, transaction sẽ tiến hành lock các dòng bị ảnh hưởng ở chế độ độc quyền. Do đó, các transaction khác không thể chạy lệnh DML trên cùng dòng với transaction kia mà phải chờ cho tới khi transaction kia kết thúc.

Transaction chứa lệnh DML cũng không cần lock các dòng được trả về từ câu truy vấn con (nếu có) của lệnh DML đó.

Câu truy vấn trong transaction có thể thấy sự thay đổi dữ liệu từ các lệnh DML xảy ra trước trong cùng transaction, và không thể thấy sự thay đổi dữ liệu từ các lệnh DML xảy ra trong các transaction khác.

Khi chạy lệnh DML, bên cạnh việc lock exclusive row, transaction còn cần lock row exclusive trên bảng chứa các dòng bị ảnh hưởng. Nếu transaction đó đã lock bảng thuộc một trong các loại share, share row exclusive hoặc exclusive từ trước thì việc lock row exclusive không cần nữa. Nếu transaction đó đã lock bảng thuộc loại row share từ trước thì lock có sẵn này sẽ được chuyển thành row exclusive một cách tự động.

5.2.DDL lock

DDL lock có chức năng bảo vệ cấu trúc của đối tượng schema (schema object) khi nó đang tham gia vào một câu lệnh DDL nào đó. Cần nhớ rằng khi hoàn thành, lệnh DDL sẽ tự động làm chấm dứt transaction (implicit commit).

Ví dụ: Trong khi một thủ tục (procedure) đang được dịch, nhờ vào DDL lock mà các bảng do thủ tục đó sử dụng sẽ không thể bị xóa hay thay đổi cấu trúc.

DDL lock do Oracle tiến hành một cách tự động. Người dùng không thể gọi DDL lock. Khi tiến hành DDL lock thì Oracle chỉ lock những đối tượng cần thiết.

DDL lock gồm các loại: excluse DDL lock (lock cấu trúc độc quyền), share DDL lock (lock cấu trúc chia sẻ) và breakable parse lock.

Exclusive DDL lock

Đa số các lệnh DDL đều dùng exclusive DDL lock. DDL lock có chức năng ngăn cản sự xung đột khi có nhiều lệnh DDL cũng được tiến hành trên một đối tượng schema.

Ví dụ: Nếu một table đang được alter thì nó không thể bị drop (và ngược lại).

Nếu lệnh DDL cần tiến hành trên một đối tượng đang bị DDL lock, nó sẽ chờ đến khi đối tượng đó không còn bị lock rồi mới thực thi được.

Các lệnh DDL cũng thực hiện DML lock trên đối tượng đang được chỉnh sửa.

Share DDL lock

Một số lệnh DDL cần dùng share DDL lock để ngăn cản sự xung đột nhưng vẫn cho phép các lệnh DDL tương tự cùng chạy đồng thời trên đối tượng mà nó đang xử lý.

Ví dụ:

  • Khi câu lệnh CREATE PROCEDURE được thực thi, nó sẽ tiến hành share DDL lock trên các bảng mà thủ tục tham chiếu.
  • Trong khi các bảng trên đang bị share DDL lock thì các transaction khác cũng có thể chạy lệnh tạo thủ tục tham chiếu vào cùng các bảng đó một cách đồng thời.

Các transaction không thể tiến hành exclusive DDL lock trên đối tượng đang được share DDL lock, do đó đối tượng đang được share DDL lock sẽ không thể bị xóa hoặc thay đổi cấu trúc từ đó vẫn ngăn cản được các xung đột có thể xảy ra.

Breakable parse lock

Một câu lệnh SQL (hoặc thủ tục PL/SQL) trong shared pool sẽ giữ parse lock trên các đối tượng schema mà nó tham chiếu. Nhờ vào parse lock, Oracle biết rằng các lệnh SQL (hoặc thủ tục PL/SQL) trong shared pool cần phải dịch lại khi đối tượng mà chúng tham chiếu bị chỉnh sửa cấu trúc (hoặc bị xóa).

Parse lock không có chức năng bảo vệ các đối tượng mà nó đang lock. Parse lock sẽ bị hủy (break) nếu đối tượng mà nó đang lock bị thay đổi trong các câu lệnh DDL. Do đó, parse lock được gọi là breakble parse lock.

Thời hạn của DDL lock

Thời hạn của DDL lock tùy thuộc vào loại DDL lock.

Với share DDL lock và excluse DDL lock thì thời hạn của chúng là trong khi câu lệnh DDL đang chạy.

Với breakable parse DDL lock thì sẽ tồn tại trong khi mà lệnh SQL (hay thủ tục PL/SQL) liên kết với nó còn tồn tại trong shared pool.

DDL lock và cluster

Lệnh DDL trên một cluster sẽ tiến hành DDL lock trên chính cluster và các bảng và materialized view có dùng cluster đó.

Lệnh DDL trên bảng hoặc materialized view sẽ tiến hành share DDL lock trên các cluster mà chúng sử dụng, từ đó bảo vệ cluster không bị xóa khi lệnh DDL đang thực hiện.

6.Latch và internal lock

Latch và internal lock bảo vệ cấu trúc nội bộ của CSDL và bộ nhớ. Cả hai loại lock này đều do Oracle sử dụng và người dùng không thể can thiệp.

6.1.Latch

Latch khá đơn giản. Nó có chức năng bảo vệ ở cấo độ thấp cho các cấu trúc dữ liệu chia sẻ trong vùng SGA (system global area).

Ví dụ: Latch bảo vệ danh sách các user đang kết nối vào CSDL và bảo vệ cấu trúc dữ liệu dùng để mô tả các block dữ liệu trong vùng nhớ đệm (buffer cache).

Một tiến trình nền (background process) sẽ tiến hành latch trong thời gian rất ngắn trong khi nó đang chỉnh sửa hoặc tìm kiếm trên các cấu trúc đó. Sự cài đặt latch là tùy vào hệ điều hành

6.2.Internal lock

Internal lock phức tạp hơn và ở cấp độ cao hơn so với latch và phục vụ cho nhiều mục đích khác nhau.

Dictionary cache lock

Lock này diễn ra trong thời gian rất ngắn, có chức năng bảo vệ entry trong dictionary cache trong khi các entry đang được user chỉnh sửa. Nó bảo đảm rằng các câu lệnh đang được phân tích (parse) sẽ không bao giờ “nhìn thấy” cấu trúc chưa nhất quán của các đối tượng.

Dictionary cache lock có hai mức là share và exclusive. Share lock sẽ được hủy khi câu lệnh được parse xong. Exclusive lock được hủy khi lệnh DDL chạy xong.

File and Log Management Locks

Loại lock này bảo vệ các tập tin khác nhau.

Ví dụ: Loại lock này bảo vệ control file, từ đó trong một thời điểm chỉ có tối đa một tiến trình có thể thay đổi nó. Loại lock này cũng bảo vệ sự sử dụng và lưu trữ redo log file. thêm vào đó nó cũng bảo vệ các datafile, từ đó cho phép chỉ một (chế độ độc quyền) hay nhiều (chế độ chia sẻ) instance được sử dụng một data file.

Dạng lock này bảo vệ trạng thái của tập tin nên nó có thể kéo dài.

Tablespace và rollback segment lock

Như tên gọi, loại lock này có chức năng bảo vệ các tablespace và rollback segment.

Ví dụ: Các instance truy cập vào database sẽ phải kiểm tra xem tablespace online hay offline. Còn các rollback segment được lock để đảm bảo rằng mỗi segment chỉ được ghi dữ liệu bởi một instance.

7.Explicit locking

Oracle luôn tự động lock để đảm bảo tính đồng thời, tính đúng đắn của dữ liệu và tính nhất quán khi đọc dữ liệu ở cấp câu lệnh. Tuy nhiên người dùng có thể tự tự lock theo ý mình, trong các trường hợp sau:

  • Ứng dụng cần tính nhất quán khi đọc dữ liệu ở cấp độ transaction hoặc các thao tác đọc lặp đi lặp lại. Nói cách khác, các câu truy vấn cần lấy ra các khối dữ liệu thống nhất trong suốt transaction mà không bị ảnh hưởng bởi những thay đổi từ các transaction khác. Ta có thể bảo đảm tính nhất quán khi đọc ở cấp transaction bằng cách dùng explicit locking, tạo ra read only transaction, serializable transaction hoặc thay đổi chế độ lock mặc định.
  • Ứng dụng cần tạo ra transaction để truy cập lập tức vào tài nguyên mà không phải chờ đợi các transaction khác.

Chế độ lock mặc định của Oracle có thể được thay đổi ở cấp transaction hoặc session.

Ở cấp transaction:

  • Dùng câu lệnh SET TRANSACTION ISOLATION LEVEL.
  • Dùng câu lệnh LOCK TABLE.
  • Dùng câu lệnh SELECT với tùy chọn FOR UPDATE.

Ở cấp session:

  • Đặt các chế độ cô lập transaction bằng lệnh ALTER SESSION.

8.Oracle Lock Management Services

Với Oracle Lock Management Services, lập trình viên có thể tạo ra các khối PL/SQL với khả năng:

  • Tạo ra một lock thuộc loại nào đó.
  • Đặt cho lock một cái tên duy nhất mà các thủ tục khác có thể nhận ra.
  • Đổi loại của một lock
  • Hủy bỏ một lock.

Các lock trong khối lệnh PL/SQL cũng là Oracle lock nên có đầy đủ đặc trưng và tính năng lock của Oracle , bao gồm khả năng phát hiện dead lock. Lock được tạo ra bởi người dùng sẽ không xung đột với lock của Oracle vì chúng được đặt tên với tiền tố UL.

Oracle Lock Management Services được sử dụng thông qua các thủ tục trong package DBMS_LOCK.

More information in SQL 9i References.


Gửi phản hồi

Mời bạn điền thông tin vào ô dưới đây hoặc kích vào một biểu tượng để đăng nhập:

WordPress.com Logo

Bạn đang bình luận bằng tài khoản WordPress.com Log Out / Thay đổi )

Twitter picture

Bạn đang bình luận bằng tài khoản Twitter Log Out / Thay đổi )

Facebook photo

Bạn đang bình luận bằng tài khoản Facebook Log Out / Thay đổi )

Google+ photo

Bạn đang bình luận bằng tài khoản Google+ Log Out / Thay đổi )

Connecting to %s

Danh mục

%d bloggers like this: