What I notice is that ShouldRetryOn() in the strategy is not called on the first "hit" to the database with Entity Framework and dotConnect for Oracle. On the first call, if the database is unavailable (suppose the service is turned off), the exception will just be thrown to the calling code, and execution will never enter ShouldRetryOn(). The ShouldRetryOn() method is only reached after a successful command/query has been made to the database, and subsequent ones fail (e.g. make 1 query, then turn off the Oracle Service, and try it again. On the second time, ShouldRetryOn() will get executed). The behavior with the standard System.Data.SqlClient provider is different; it will fall into ShouldRetryOn() to determine if it should retry the exception on the first call to the database. The SqlClient behavior is substantially easier to work with in that calls around the EF context do not have to be wrapped in the execution strategy (unless working with a user initiated transaction). From what I'm seeing with the dotConnect Oracle provider, in order to retry any call to the database, I need to manually wrap the code as follows:
Code: Select all
var executionStrategy = new AlwaysRetryStrategy();
executionStrategy.Execute(() =>
{
using(var context = new ToDoContext())
{
var count = context.ToDos.Count();
}
});
I created a sample unit test project that distills it down to a very simple model/EF code first context, a simple retry strategy that attempts to always retry the exception, and a few simple tests with instructions to illustrate the problem. It can be downloaded here. just change the app.config for your own connection strings.