Để xử lý sự cố đồng thời, khóa - mọi hình thức khóa, cho dù đó là hàng, bảng hoặc cơ sở dữ liệu có khóa giải pháp tốt hay không?Khóa để xử lý đồng thời-- một ý tưởng hay?
Nếu không, cách xử lý vấn đề tương tranh?
Để xử lý sự cố đồng thời, khóa - mọi hình thức khóa, cho dù đó là hàng, bảng hoặc cơ sở dữ liệu có khóa giải pháp tốt hay không?Khóa để xử lý đồng thời-- một ý tưởng hay?
Nếu không, cách xử lý vấn đề tương tranh?
Nếu bạn tin rằng Oracle, không, không hề. Đó là bởi vì Oracle đã đi đến độ dài lớn để tránh nó.
Vấn đề là người đọc có thể chặn người đọc và người viết chặn người đọc và người viết phải chờ cho đến khi tất cả người đọc đã hoàn thành với một hàng trước khi có thể viết. Điều đó làm chậm quá trình viết và người gọi của nó. Các khóa độc quyền (để viết) được giữ ở cuối giao dịch, trong trường hợp giao dịch phải được khôi phục - điều này sẽ ngăn các giao dịch khác nhìn thấy giá trị mới cho đến khi giao dịch được thực hiện.
Trong thực hành khóa nói chung là tốt nếu không có quá nhiều tranh chấp, giống như với bất kỳ chương trình đồng thời nào. Nếu có quá nhiều tranh chấp cho một hàng/trang/bảng (không phải nhiều máy chủ cơ sở dữ liệu thực hiện toàn bộ khóa DB), nó sẽ làm cho các giao dịch thực hiện lần lượt thay vì đồng thời.
Oracle sử dụng phiên bản hàng, thay vì khóa một hàng để viết, phiên bản mới của hàng được tạo ra thay thế.Người đọc cần lặp lại lần đọc của họ, hãy nhớ phiên bản nào của hàng họ đọc. Tuy nhiên, một lỗi sẽ xảy ra nếu một người đọc ghi nhớ lần đọc của nó cố gắng cập nhật một hàng đã được một nhà văn khác cập nhật kể từ khi giao dịch này đọc nó; điều này là để ngừng cập nhật bị mất. Để đảm bảo bạn có thể cập nhật một hàng, bạn phải nói rằng SELECT là FOR UPDATE; nếu bạn làm điều đó, nó sẽ mất một khóa - chỉ một giao dịch có thể giữ một hàng FOR UPDATE tại một thời điểm, và một giao dịch xung đột phải đợi.
SQL Server 2005 và sau đó hỗ trợ Chụp nhanh cách ly, là tên của họ cho phiên bản hàng. Một lần nữa, bạn nên yêu cầu cập nhật khóa nếu bạn cần cập nhật một số dữ liệu bạn vừa đọc - trong SQL Server, sử dụng WITH (UPDLOCK).
Một vấn đề nữa với khóa là khả năng của deadlocks. Điều này chỉ đơn giản là nơi hai giao dịch từng nắm giữ một khóa trên một nguồn lực các nhu cầu khác, hoặc nói chung một chu kỳ giao dịch giữ khóa mà mỗi khác cần phải tiến bộ. Các máy chủ cơ sở dữ liệu nói chung sẽ phát hiện bế tắc này và giết một trong các giao dịch, lăn nó trở lại - sau đó bạn cần phải thử lại hoạt động. Bất kỳ tình huống nào mà bạn có nhiều giao dịch đồng thời sửa đổi cùng một hàng đều có khả năng bị bế tắc. Bế tắc sẽ xảy ra nếu các hàng được chạm vào theo thứ tự khác; rất khó để thực thi thứ tự mà máy chủ cơ sở dữ liệu sẽ sử dụng (thường bạn muốn trình tối ưu hóa chọn thứ tự nhanh nhất, thứ nhất thiết sẽ không nhất quán trong các truy vấn khác nhau).
Nói chung tôi sẽ đề nghị giống như với luồng - đi với khóa cho đến khi bạn có thể chứng minh rằng chúng đang gây ra vấn đề về khả năng mở rộng, sau đó tìm hiểu cách làm cho các phần quan trọng nhất không bị khóa.
Tôi nghĩ là không, bởi vì đó là tất cả các cách "giảm" và làm cho ứng dụng của bạn phức tạp hơn. Hầu hết các ngôn ngữ có kỹ thuật xử lý đồng thời xuất sắc, và thậm chí sau đó cách tốt nhất là viết mã có thể xử lý đồng thời "nguyên bản".
Để biết thêm về đồng thời trong Java: http://java.sun.com/docs/books/tutorial/essential/concurrency/index.html
Bạn có nghĩa là để xử lý đồng thời trong ứng dụng của bạn, hoặc để giải quyết một vấn đề đồng thời bạn đang gặp với cơ sở dữ liệu. Nếu trước đây, nó không tấn công tôi như một cách tiếp cận tốt. Nếu sau này, đây có thể là câu trả lời duy nhất của bạn mà không cần thiết kế lại các lược đồ của bạn.
Khóa cơ sở dữ liệu - trái ngược với khóa bảng hoặc hàng - là một cách xấu để xử lý đồng thời; nó quy định đồng thời.
Bạn có thể giải thích chi tiết câu trả lời của mình không? Đó là một cách xấu để đối phó với nó bởi vì nó ngăn cản nó? – DOK
Tôi nghĩ điểm của anh ấy là bạn khóa cơ sở dữ liệu, bạn không có đồng thời, vì nó bị khóa. –
@ dok1: Mitchel đã đúng. Nếu bạn khóa cơ sở dữ liệu (ở chế độ độc quyền), thì không có truy cập đồng thời nào cả. Nếu bạn khóa cơ sở dữ liệu ở chế độ chỉ đọc, thì bạn có thể có nhiều người đọc cơ sở dữ liệu, nhưng không ai có thể sửa đổi nó. (Tôi biết một DBMS cung cấp khóa độc quyền trên cơ sở dữ liệu.) –
Trước tiên bạn phải xác định mục tiêu của mình. Trong trường hợp yêu cầu đồng thời, bạn muốn giành được người dùng cuối hoặc người dùng đầu tiên. Khóa cơ sở dữ liệu chắc chắn là một cách xấu. Cố gắng khóa bàn/hàng càng muộn càng tốt và nhả khóa càng sớm càng tốt.
Có nhiều cách thay thế hợp lý để bạn phải tự khóa mã DMBS. Hãy ghi nhớ một số loại khóa thực sự luôn luôn xảy ra (hành động nguyên tử, vv) nhưng điều quan trọng là bạn không muốn đến đó nếu bạn không phải. Bạn không muốn ăn tối với các nhà triết học nếu bạn không phải làm vậy. Giao dịch là một cách để nhận được xung quanh khóa, nhưng đó là chủ yếu cho các cam kết. Sử dụng một trường đánh dấu/cho biết bản ghi là bẩn (mẫu bit bẩn) là một cách khác, chỉ cần chắc chắn rằng bạn đang làm như vậy theo cách truy cập nguyên tử. Ngôn ngữ thường có một giải pháp thích hợp như được tham chiếu bởi các bài đăng trước, tuy nhiên ngôn ngữ thường chỉ hỗ trợ ứng dụng, quy trình xử lý, đồng thời cấp và đôi khi đồng thời phải là trong cơ sở dữ liệu. Tôi không muốn cho rằng bạn có một lớp ứng dụng phong phú, nhưng nếu bạn có nhiều lớp trừu tượng xử lý điều này cho bạn. TopLink by Oracle là miễn phí và là anh trai mạnh mẽ hơn của Hibernate cả hai giúp bạn quản lý cơ sở dữ liệu của bạn đồng thời thách thức thông qua trừu tượng, bit bẩn, bộ nhớ đệm, và khóa lười biếng. Bạn thực sự không muốn tự mình thực hiện, trừ khi bạn đang viết mã cho một trường học hoặc dự án cá nhân. Hiểu được vấn đề, nhưng đứng trên vai những người khổng lồ.
mã có thể xử lý đồng thời "nguyên bản" ... bất kỳ đề xuất nào về cách thực hiện? – Graviton
Tôi nghĩ rằng anh ấy có nghĩa là sử dụng các tính năng của ngôn ngữ lập trình hoặc thư viện như java.util.concurrent. –
Có. Xem thêm http://java.sun.com/docs/books/tutorial/essential/concurrency/index.html – Rolf