Yes – this is a post about an error – one that I could find nothing on Google about. It’s a quick one, about the Gentle persistence framework for .Net programming.
Basically, I enjoy working with Gentle, but I started to experience an odd issue the other day. I started to get occasional odd errors on the first Persist() command in a batch script. One of the errors had the message including the error above; ‘Gentle.Common.Error.NoProperty’. It was complaining that the primary key of the table did not exist… and clearly viewing the code generated by MyGeneration showed the property did exist. The weird thing was, I could step through the code and get the error, cancel the job, and restart the job and it would be fine. The next day, the same thing happened; the first run failed, the next one was fine.
I don’t have a firm answer to this, but I believe the problem was because my first Persist() calls (for an insert) was in fact in a thread; and there were two or more calls occurring roughly in parallel. I only know this from examining exciting SQL trace logs; but every time that a process or application space starts up in an environment, the Gentle dll contacts the DB and asks for various information about the data-model. I’m not 100% sure what it’s doing, as the data model has effectively already been specified by using MyGeneration. What we see on our DB is these calls occurring from our batch-scripting machine every few minutes- but not from our web application servers that run all the time…
Anyway, what I believe was happening was that the Gentle dll is not threadsafe on these first calls to get the data model. My first calls to Persist() were inserts oif new records, so it was these calls that actually resulted in calls to the DB to retrieve data model information… and obviously the calls from the different threads were somehow colliding so that one of the following conditions occurred:
- A thread thinking the data had been retrieved, when in fact it had not (e.g. the error noted);
- A thread thinking the data had not been retrieved, retrieving it again, and then hitting the opposite error that was something to do with a dictionary (read ‘Table’) not being able to have more than one entry (read ‘Column’) of the same name.
The issue on my debug machine was that the Visual Studio web service keeps active in the background once started the first time, so second and later runs of Gentle queries did not need to requery the DB until the next day, when I had clkosed the IDE, lost the DB connection and so on.
My solution was simple, but clunky; make a single database read using the Gentle framework in the master process before splitting into threads… this allows the framework to get the data while-you-wait, and then you can trust the framework once you get into the threaded bits.
You might be wondering, as I did, that if Gentle is not multi-thread safe at start-up, is it safe in general for multi-threaded applications? The only answer I can come up with to that question is Yes – as we have been using it for fairly heavy usage on a couple of webservers (which service multiple transactions from different users on different threads) without problems…