2010-03-22 28 views
7

sơ bộ:MySQL: Các giao dịch trên nhiều chủ đề

Tôi có một ứng dụng mà duy trì một hồ bơi thread khoảng 100 bài. Mỗi luồng có thể kéo dài khoảng 1-30 giây trước khi tác vụ mới thay thế nó. Khi một luồng kết thúc, luồng đó sẽ hầu như luôn dẫn đến việc chèn 1-3 bản ghi vào một bảng, bảng này được sử dụng bởi tất cả các luồng. Ngay bây giờ, không có hỗ trợ giao dịch tồn tại, nhưng tôi đang cố gắng để thêm rằng bây giờ. Ngoài ra, bảng được đề cập là InnoDB. Vì vậy, ...

Goal

Tôi muốn thực hiện một giao dịch cho việc này. Các quy tắc cho hay không giao dịch này cam kết hoặc rollback cư trú trong chủ đề chính. Về cơ bản có một hàm đơn giản sẽ trả về một boolean.

  1. Tôi có thể triển khai giao dịch trên nhiều kết nối không?
  2. Nếu không, có thể có nhiều chuỗi chia sẻ cùng một kết nối không? (Lưu ý: có rất nhiều chèn chèn ở đây, và đó là một yêu cầu).

Trả lời

3

Vâng, như được nêu trong một câu trả lời khác, bạn không thể tạo giao dịch trên nhiều kết nối. Và bạn có thể chia sẻ kết nối duy nhất trên các chuỗi. Tuy nhiên bạn cần phải rất cẩn thận với điều đó. Bạn cần đảm bảo rằng chỉ có một luồng đang ghi vào kết nối cùng một lúc. Bạn không thể chỉ có nhiều chủ đề nói chuyện trên cùng một kết nối mà không đồng bộ hóa các hoạt động của họ theo một cách nào đó. Những điều tồi tệ có thể sẽ xảy ra nếu bạn cho phép hai chủ đề để nói chuyện cùng một lúc (bộ nhớ bị hỏng trong thư viện khách hàng, vv). Sử dụng một mutex hoặc phần quan trọng để bảo vệ các cuộc hội thoại kết nối có lẽ là con đường để đi.

-Do

+0

Có lẽ, tôi nghĩ rằng tôi có thể suy nghĩ lại điều này bằng cách chỉ cần chờ chủ đề trên bài kiểm tra của chủ đề chính để hoàn thành trước khi bắt đầu. – Zombies

+0

Chỉ là một ý nghĩ, không kiểm tra điều đó: nếu bạn thực hiện các hàm 'start_transaction()' và 'commit()'/'rollback()' của riêng mình, và bạn khóa một mutex trong 'start_transaction()' và mở khóa nó trên giao dịch cuối cùng, các giao dịch sẽ an toàn hơn nhiều để sử dụng trong các chủ đề. Tôi không nói rằng nó sẽ hoạt động như một kết nối khác. Nó chỉ là đôi khi bạn bắt đầu giao dịch trong các chủ đề và bạn dựa vào chúng là nguyên tử. Cũng lưu ý rằng mysql sais rằng chỉ có một truy vấn tại một thời điểm nên chạy trong tất cả các luồng. Điều đó bao gồm từ chạy truy vấn để hoàn tất tìm nạp kết quả. – NickSoft

+0

Thông tin liên lạc qua kết nối cần phải được tuần tự hóa. Một cách tiếp cận là phải có một chuỗi giao tiếp chuyên dụng và có các luồng khác làm bất cứ công việc nào là cần thiết, sau đó chuyển các kết quả lên đến luồng giao tiếp, mà nối tiếp các câu lệnh. –

4

1) Không, giao dịch được giới hạn trong một kết nối DB duy nhất.

2) Có, kết nối (và giao dịch) có thể được chia sẻ trên nhiều luồng.

+0

Đối với (2) và nếu bảng là INNODB, tôi đảm bảo rằng có nhiều lần chèn xảy ra cùng một lúc? – Zombies

+0

@Zombies Có, mặc dù tôi không có kinh nghiệm với InnoDB và Giao dịch, tôi tin rằng điều đó sẽ ổn. Tôi thấy không có lý do gì để nó không hoạt động. –

0

Chia sẻ kết nối giữa nhiều chuỗi thường được thực hiện bằng cách sử dụng một nhóm kết nối. Mỗi luồng có thể yêu cầu một kết nối từ các hồ bơi, sử dụng nó cho các mục đích của nó (một hoặc nhiều giao dịch, cam kết hoặc cuộn lại) và đưa nó trở lại hồ bơi khi công việc được hoàn thành.

Đây là những gì máy chủ ứng dụng cung cấp cho bạn. Họ cũng sẽ chăm sóc các giao dịch, i. e. khi phương thức yêu cầu giao dịch kết thúc bình thường, các thay đổi được cam kết, nếu nó ném một ngoại lệ, giao dịch cơ sở dữ liệu được khôi phục.

Tôi khuyên bạn nên xem xét Java EE 5 hoặc 6 - nó rất dễ sử dụng và thậm chí có thể được sử dụng trong các hệ thống nhúng. Để bắt đầu dễ dàng, hãy xem Netbeans và máy chủ ứng dụng Glassfish. Tuy nhiên, các khái niệm chung áp dụng cho tất cả các máy chủ ứng dụng.

Đối với InnoDB, sẽ không có bất kỳ sự cố nào khi xử lý nhiều giao dịch. Dưới sự giám sát của máy chủ ứng dụng, bạn có thể tập trung vào logic nghiệp vụ và không phải lo lắng về các bản cập nhật bằng văn bản hoặc bất kỳ ai nhìn thấy các bản cập nhật/chèn trước khi giao dịch mà chúng bắt nguồn từ đã được cam kết.

InnoDB sử dụng MVCC (điều khiển đồng thời nhiều phiên bản), hiển thị hiệu quả từng giao dịch với ảnh chụp nhanh toàn bộ cơ sở dữ liệu tại thời điểm bắt đầu. Bạn có thể đọc thêm về MVCC tại đây trong một câu hỏi có liên quan: Question 812512

+0

Điều này sẽ không được triển khai trên J2EE. Nhưng nó sẽ được sử dụng một hồ bơi kết nối J2SE trong tương lai có. Vì vậy, tôi lấy nó mà tôi có thể rollback trên tất cả các kết nối trong hồ bơi kết nối ...? – Zombies

+0

Có, MVCC mặc định là mức cô lập giao dịch "đọc lặp lại", nghĩa là khi giao dịch đã đọc bit dữ liệu đầu tiên, nó sẽ không thấy bất kỳ cập nhật nào từ các giao dịch khác, ngay cả khi chúng được cam kết. Chỉ khi giao dịch hiện tại được cam kết hoặc quay trở lại giao dịch tiếp theo trên kết nối này sẽ thấy dữ liệu mới từ tất cả những người khác đã cam kết đến thời điểm đó. –

+0

Chỉ cần rõ ràng: Bạn sẽ không thể phát hành một lệnh "rollback all open transactions" đơn lẻ. Nhưng điều này thường không phải là những gì bạn sẽ muốn anyway - nếu vậy, tôi nghĩ rằng bạn cần phải làm sáng tỏ thêm một chút về hệ thống của bạn, bởi vì nó sẽ không có vẻ đúng. –

Các vấn đề liên quan