2010-04-23 35 views
12

Tôi muốn thêm khối cứu trợ bắt đầu ... vào một trong các trình điều khiển của tôi tạo phương pháp, để ghi lại thông tin tốt hơn và xây dựng thông báo lỗi chính xác để quay lại máy khách. Liệu sự giải cứu trong bất kỳ cách nào 'làm gián đoạn' quá trình rollback?Đường ray có thực hiện khôi phục nếu tôi sử dụng bắt đầu ... cứu hộ không?

Tôi giả định đường ray tự động thực hiện khôi phục. Khi nào nó xảy ra? Nó đã xảy ra vào thời điểm tôi nhận được trong điều khoản cứu hộ?

Tôi đang sử dụng mySQL trên Dreamhost và tôi nghĩ rằng họ sử dụng innoDB.

+0

Hãy xem trong câu trả lời này: http://stackoverflow.com/questions/14329877/render-failing-to-render-correct-template-in-rescue-from- activerecordrollback/35731832 # 35731832 – monteirobrena

Trả lời

0

Chỉ cần sử dụng begin ... rescue không đủ để khôi phục giao dịch. Bạn cần sử dụng:

ModelName.transaction do 
end 

Điều này được thực hiện rõ ràng khi gọi để lưu, để tất cả các cuộc gọi lại của bạn được thực hiện cùng nhau. Ngoại lệ bạn đang mắc phải trong khối cứu hộ của bạn là gì? Bạn đang đáp ứng điều gì? Loại lỗi nào?

+0

Tôi đang bị deadlocks. Tôi không nghĩ rằng tôi sẽ có đủ không gian ở đây để mô tả nó. Đó là một trò chơi bài. Nhưng trong một phương thức gọi lại after_save cho mô hình PlayerAction của tôi, tôi tạo một cá thể PlayerAction khác. Tôi nhận được deadlocks trên các mô hình liên quan của họ. Khi điều đó xảy ra, tôi muốn khôi phục toàn bộ điều, bao gồm mô hình PlayerAction đầu tiên và các mối quan hệ của nó đã được tạo ra. Có vẻ như bạn đang nói rằng đường ray KHÔNG thực hiện giao dịch tự động, đúng không? Tôi phải bắt đầu một cách rõ ràng và kích hoạt một rollback? Có tài nguyên ở đâu đó cho việc này không? Tôi đã tìm kiếm ... – user26270

+0

Nó thực hiện giao dịch rõ ràng nhưng chỉ trên các phương thức như lưu và update_attributes. Vì vậy, after_save của bạn sẽ chạy trong cùng một giao dịch. – jonnii

+0

Tôi không chắc chắn nên đề xuất gì về deadlocks, đôi khi bạn có thể sắp xếp lại mọi thứ để tránh chúng. Có một vài plugin để thử lại trên deadlocks (http://github.com/rails/deadlock_retry). Có thể đáng xem những thứ đó. – jonnii

14

Tôi đã thử nghiệm điều này. Nó có vẻ như nếu cứu hộ của bạn bắt được ngoại lệ mà có thể đã gây ra rollback, một phần của giao dịch đã xảy ra được cam kết. Trong trường hợp của tôi, tôi muốn cơ sở dữ liệu cuộn lại theo cách trước khi giao dịch bắt đầu, nhưng tôi vẫn muốn xử lý ngoại lệ.

tôi đã kết thúc với điều này:

self.transaction do 
    first_operation 
    begin 
    operation_that_might_violate_db_constraint 
    rescue ActiveRecord::RecordNotUnique 
     #deal with the error 
     raise ActiveRecord::Rollback #force a rollback 
    end 
end 

Phần raise ActiveRecord::Rollback đảm bảo các giao dịch được hoàn toàn cuộn lại. Không có nó, những thay đổi từ first_operation sẽ kết thúc bằng việc cam kết.

ActiveRecord :: Rollback là một loại ngoại lệ đặc biệt không bong bóng trên mức của giao dịch, vì vậy bạn sẽ không kết thúc với ngoại lệ chưa thực hiện mà hiển thị trang lỗi.

Tôi không chắc đây là cách làm tiêu chuẩn vàng, nhưng có vẻ như nó hoạt động.

+0

lưu ý rằng nếu bạn nắm bắt được ngoại lệ bên trong khối giao dịch và bạn muốn làm một cái gì đó trong việc giải cứu như gửi một email, nó sẽ thất bại vì giao dịch ngăn chặn nó. –

-2

Bạn cũng có thể thử câu trả lời của tôi cho rollback, bắt và render cho phương pháp tạo ra bằng cách sử dụng ActiveRecord :: Base.transaction: - Click Here

Cảm ơn

-1

Rollback không được xử lý.

ví dụ:

create_table "helps", :force => true do |t| 
    t.string "title",       :null => false 
    t.text  "content" 
end 

#Rails console 
Help.transaction do 
    Help.create! title: "aaa" 
    begin 
    Help.create! content: "111" 
    rescue 
    p "create error." 
    end 
    Help.create! title: "bbb" 
end 

#get this 
>> "create error." 
Help.count 
>> 2 
Các vấn đề liên quan