I’ve got some code that more or less looks like this:
class Project < ActiveRecord::Base
def create_new_document
document = Document.new
document.attributes = { "project_id" => self.id,
"attribute2" => "etc..."}
if document.save
new_document_page = DocumentPage.new
new_document_page.attributes = { "document_id" => new_document.id,
"attribute2" => "etc..." }
new_document_page.save
end
end
end
So, the strange thing is that even though the document.save call is
sometimes failing and is wrapped in an “if” statement, it still tries to
create the document page which ,of course, causes DB error since the
new_document.id is nil. Also, I get “Mysql::Error: Cannot add or update
a child row: a foreign key constraint fails” on the Project update sql
because the document_id is the actual object_id instead of the id. The
update statement is trying to put a value like “-618357298” instead of
the document id (which doesn’t exist since it didn’t get saved.
The reason I’m not wrapping both saves in a transaction is because I’m
using attachment_fu to upload the document to amazon S3 and the save on
the document times out while waiting for the document pages to save. The
pages are also being uploaded to S3, and all this uploading takes time.
I’m trying to take advantage of attachment_fu’s automatic uploading when
calling save instead of pushing this off to a background job.
I’m running load testing by creating background jobs which create
projects and thus documents and pages. Most of the time everything
works fine, but under heavy load I get these errors but also rarely
under light load.
It seems like mysql is telling rails that the row was saved but it
wasn’t. The errors returned in regards to the document pages reference
a document id that doesn’t exist in the database. So, I see id skips in
the document table. For instance, the document page error references
document id 939 and the ids in the document table go 932, 934, 935…
In load testing, I have up to 5 app servers selecting from, inserting
into and updating the database. As I said, the errors are less with
medium load, but also happen randomly under very light load. I’m using
the deadlock_retry plugin which resolved some deadlocking issues I was
having.
Ok, so has anyone experienced something similar? It seems as though I
need to beef up the DB server, but the errors on light load suggest
something else.
Any feedback is much appreciated.
Thanks,
Shagy