2008-09-17 42 views
6

Tôi đang sử dụng mysql ++ để kết nối với cơ sở dữ liệu MySQL để thực hiện một loạt truy vấn dữ liệu. Do thực tế là các bảng tôi đang đọc từ liên tục được ghi vào, và rằng tôi cần một cái nhìn nhất quán của dữ liệu, tôi khóa các bảng đầu tiên. Tuy nhiên, MySQL không có khái niệm 'NOWAIT' trong truy vấn khóa của nó, do đó nếu các bảng bị khóa bởi một cái gì đó khác mà giữ chúng bị khóa trong một thời gian dài, ứng dụng của tôi ngồi đó chờ đợi. Những gì tôi muốn làm là để có thể trở lại và nói điều gì đó như 'Khóa không thể có được' và thử lại sau vài giây. Nỗ lực chung của tôi tại thời gian chờ này là dưới đây.Cách hết thời gian chờ truy vấn mysql ++ trong C++

Nếu tôi chạy sau khi khóa bảng trên cơ sở dữ liệu, tôi nhận được thông báo rằng thời gian chờ được nhấn, nhưng tôi không biết làm thế nào để sau đó nhận được dòng mysql_query để chấm dứt. Tôi đánh giá cao bất kỳ trợ giúp/ý tưởng!


volatile sig_atomic_t success = 1; 

void catch_alarm(int sig) { 
     cout << "Timeout reached" << endl; 
     success = 0; 
     signal(sig,catch_alarm); 
} 

// connect to db etc. 
// *SNIP 

signal (SIGALRM, catch_alarm); 
alarm(2); 
mysql_query(p_connection,"LOCK TABLES XYZ as write"); 

Trả lời

0

Bạn có thể thực hiện truy vấn chặn trong một chuỗi khác và không bao giờ bị làm phiền với thời gian chờ. Khi một số dữ liệu đến, bạn thông báo cho luồng cần biết về trạng thái giao dịch.

0

Nếu tôi đã viết từ đầu tôi sẽ làm điều đó, nhưng đây là một ứng dụng máy chủ mà chúng tôi đang thực hiện nâng cấp thay vì làm lại lớn.

0

thay vì cố gắng thực hiện giao dịch giả mạo bằng khóa bảng, tại sao không chuyển sang bảng innodb nơi bạn nhận giao dịch thực tế? chỉ cần đảm bảo đặt mức cô lập giao dịch mặc định thành REPEATABLE READ.

0

Như tôi đã nói, nó không phải là dễ dàng như vậy để 'chuyển đổi' hoặc tái kiến ​​trúc sư khi đây là một sống, trong hệ thống sản xuất. Tôi hơi thất vọng rằng MySQL không cung cấp phương pháp để kiểm tra ổ khóa hoặc chọn không treo chờ đợi trên một khóa.

0

Tôi không biết đây có phải là ý tưởng hay về sử dụng tài nguyên và "thực hành tốt nhất" và "sạch sẽ" và tất cả phần còn lại ... nhưng bạn đã nhiều lần mô tả còng tay ràng buộc bạn về mặt tái cấu trúc một hệ thống "sạch" ... vì vậy ở đây đi .....

Bạn có thể mở một kết nối mới, riêng biệt chỉ để gửi câu lệnh LOCK? Sau đó đóng kết nối đó khi bạn bắt được báo thức hết giờ? Bằng cách đóng/hủy kết nối được dành riêng cho câu lệnh LOCK, về cơ bản không "hủy" stat stat? Tôi không chắc chắn nếu các sự kiện như vậy sẽ xảy ra như tôi đã mô tả/đoán, nhưng có lẽ nó là một cái gì đó để kiểm tra.

0

Trải nghiệm của tôi được mô tả cho đến nay cho tôi biết rằng việc đóng kết nối trong đó truy vấn đang chạy gây ra lỗi seg. Do đó việc gửi truy vấn đó vào một kết nối khác sẽ không thực sự hữu ích, vì điều đó cũng sẽ gây ra lỗi.

3

Bạn có thể thực hiện một hành vi "hủy giống như" theo cách này:

Bạn thực hiện truy vấn trên một sợi riêng biệt, mà giữ chạy hay không timeout xảy ra. Thời gian chờ xảy ra trên chuỗi chính và đặt biến thành dấu "1" mà nó đã xảy ra. Sau đó, bạn làm bất cứ điều gì bạn muốn làm trên chủ đề chính của bạn.

Chuỗi truy vấn, khi truy vấn hoàn tất, hãy kiểm tra xem thời gian chờ đã xảy ra chưa. Nếu nó không có, nó làm phần còn lại của công việc nó cần phải làm. Nếu nó có, nó chỉ mở khóa các bảng nó vừa bị khóa.

Tôi biết nó nghe có vẻ hơi lãng phí, nhưng thời gian mở khóa phải cơ bản tức thì và bạn càng gần với kết quả bạn muốn càng tốt.

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