The readOnly attribute only prevents Apex code on the page from performing any DML, in exchange for higher governor limits (1,000,000 query rows). The sforce.connection script uses the API directly, not Apex, and is thus not subject to this restriction (it's also not subject to the 50,000 query row limit, as it can retrieve up to 50,000,000 rows as an API ...
If you're working with such high volumes of data, you might be better off using a standard Salesforce report with the report columns matching the fields you are querying (which can also easily be changed in future without changing code if needed), and the report filters matching your query's WHERE clause filters
You can then programmatically pass URL ...
You are resetting your rec variable after insert, which destroys the reference you need to the inserted object's Id:
rec = new recipient__c();
rec.Id is now null, because you erased the sObject that was in that variable.
sch = new scholarship_award__c(Recipient__c=rec.Id);
So you can't connect up the ...