Is there any published guidance for handling transient fault scenarios in SQL Azure when using WCF RIA Services backed by Entity Framework and/or Linq to SQL?
We have studied the CAT retry library (Transient Fault Handling Framework for SQL Azure) and documentation (Retry Logic for Transient Failures in SQL Azure), particularly the sections as they relate to Entity Framework and Linq to SQL.
For example, in the case of Linq to SQL, we are instructed to wrap our query/update code into an ExecuteAction and execute it with a RetryPolicy.
This article (Silverlight 4, EF 4, RIA Services & Windows Azure together) suggests that the best we can hope for is to add resiliancy to the connection. However, it appears that we may get the result we want by overriding the PersistChangeSet method on LinqToEntitiesDomainService and LinqToSqlDomainService and adding our retry there.
e.g. (Pseudo code)
protected override bool PersistChangeSet()
{
e.Result = retry.ExecuteAction(() =>
{
return base.PersistChangeSet();
});
return e.Result;
}
Any thoughts to this approach? Is there any documentation or guidance out there, specifically as relates to RIA Services?
This was originally going to be a comment but...
I recently used the RetryPolicy class with entity framework and encountered no problems.
Adding the retries is extremely simple and low impact.
The article linked is dated (May 30) which is before they added support for azure to the enterprise library. (see this announcement)
So based on the scenario described above I would say that the RetryPolicy will satisfy the requirements described.
Related
Let me first apologise for the length of the entire topic. It will be fairly long, but I wish to be sure that the message comes over clearly without errors.
Here at the company, we have an existing ASP.NET WebApplication. Written in C# ASP.NET on the .NET Framework 3.5 SP1. Some time ago an initial API was developed for this web application using WCF and SOAP to allow external parties to communicate with the application without relying on the browsers.
This API survived for some time, but eventually the request came to create a new API that was RESTfull and relying on new technologies. I was given this assignment, and I created the initial API using the Microsoft MVC 2 Framework, running inside our ASP.NET WebApplication. This took initially quiet some time to get it properly running, but at the moment we're able to make REST calls on the application to receive XML detailing our resources.
I've attended a Microsoft WebCamp, and I was immediatly sold by the OData concept. It was very similar then what we are doing, but this was a protocol supported by more players instead of our own implementation. Currently I'm working on a PoC (Proof of Concept) to recreate the API that I developed using the OData protocol and the WCF DataService technology.
After searching the Internet for getting NHibernate 2 to work with the Data Services, I succeeded in creating a ReadOnly version of the API that allows us to read out the entities from the internal business layer by mapping the incoming query requests to our Business layer.
However, we wish to have a functional API that also allows the creation of entities using the OData protocol. So now i'm a bit stuck on how to proceed. I've been reading the following article : http://weblogs.asp.net/cibrax/default.aspx?PageIndex=3
The above articly nicely explains on how to map a custom DataService to the NHibernate layer. I've used this as a base to continue on, but I have the "problem" that I don't want to map my requests directly to the database using NHibernate, but I wish to map them to our Business layer (a seperate DLL) that performs a large batch of checks, constraints and updates based upon accessrights, privledges and triggers.
So what I want to ask, I for example create my own NhibernateContext class as in the above articly, but instead rely on our Business Layer instead of NHibernate sessions, could it work? I'd probably have to rely on reflection alot to figure out the type of object I'm working with at runtime and call the correct business classes to perform the updates and deletes.
To demonstrate with a smal ascii picture:
*-----------------*
* Database *
*-----------------*
*------------------------*
* DAL(Data Access Layer) *
*------------------------*
*------------------------*
* BUL (Bussiness Layer) *
*------------------------*
*---------------* *-------------------*
* My OData stuff* * Internal API *
*---------------* *-------------------*
*------------------*
* Web Application *
*------------------*
So, would this work, or would the performance make it useless?
Or am I just missing the ball here?
The idea is that I wish to reuse whatever logic is stored in the BUL & DAL layer from the OData WCF DataService.
I was thinking about creating new classes that inherit from the EntityModel classes in the Data.Services namespace and create a new DataService object that marks all calls to the BUL & DAL & API layers. I'm however not sure where/who to intercept the requests for creating and deleting resources.
I hope it's a bit clear what I'm trying to explain, and I hope someone can help me on this.
The devil is in the details, but it sounds like the design you're proposing should work.
The DataService class is where you get to define the access rights applicable to everyone, configuration settings, and custom operations. In this scenario, I think you will be focusing more on the data context instead (the 'T' in DataService).
For the context, there are really two interesing paths: reads and writes. Reads happen through the IQueryable entry points. Writing a LINQ provider is a good chunk of work, but NHibernate already supports this, although it would return what I imagine we're calling DAL entities. You can use query interceptors to do access checks here if you can express those in terms that the database would understand.
The update path is from what I understand where you are trying to run more business logic (you mentioned validation, extra updates, etc). To do this, you'll want to focus on the IUpdatable implementation (IDataServiceUpdateProvider if you're using the latest version). Here you can use whichever objects you want - they could be DAL objects or business objects. You can do everything in the DAL and then run validation on SaveChanges(), or do everything on business objects if they validate as they go.
There are two places where you might 'jump' from one kind of objects to another. One is in the GetResource() API, where you get an IQueryable, presumably in term of DAL entities. The other is in ResolveResource(), where the runtime is asking for an object to serialize, just like it would get from an IQueryable, so it's presumably also a DAL entity.
Hope this helps - doing uniform access over non-uniform APIs can be hard, but often well worth it!
There a lot of different ways a Silverlight application can connect back to it’ server. Including
WCF - Windows Communication Foundation
REST (see also)
ADO.NET Data Services (or is this just REST?)
POX - Plain Old XML (E.g basic xml)
RIA services
For each of these please say what it’s for and when you would or wouldn’t use it. I am not looking for a great level of details just a set of “rules of thumb” for choosing between them.
(The problem is when designing your first Silverlight application knowing what to use when you don’t have time to learn all of them.)
If I was to replace Silverlight with WPF in this question what effect would it have on your answers? (I am assuming with WPF that due to firewalls and admin policies a direct connect to the database is not an option.)
My two (euro) cents:
WCF seems best suited when the service can be viewed as the business layer of the application, that is, when your service has "intelligent" operations like "CalculateDiscountForClient".
ADO.NET Data Services (indeed, just a REST implementation) seems appropriate when your application is basically data-centric and the service is simply a front-end for the database. That is, all your service methods are of type GetCustomers, CreateInvoice, etc.
RIA services is a very new technology that I haven't experimented with yet, but it seems to be useful to create applications in which the Silverlight part and the service are very tightly coupled: you define your service classes and methods in the service project, and they are automatically replicated to the Silverlight project in design time. Also, you can define both WCF-style "action" methods and ADO.NET Data Services-style "data" methods. Looks promising.
Use POX if there is a chance that you change the client part from Silverlight to any other technology (for example HTML+AJAX) in the future, since it is the most interoperable option.
About differences for WPF, the only I can think of, is that for data access, whenever possible I would use direct ADO.NET data connections (properly embedded in a data access layer, LINQ to SQL or the like) instead of ADO.NET Data Services, since it is way more flexible. I must say anyway that I have never developed anything in WPF.
We use RIA, and that's the only one of the options that I know, but I do know it, so here's some of my thoughts.
RIA isn't finished yet. It is being worked on. If you are planning to be finished soon, and you're worried about having to support something that has a potential to change quite a bit, then you might want to consider other options. If this is a new project, and you're going to be supporting it for a long time, RIA will probably get easier to use.
Having said that, I kind of think that there won't be many changes in the way the July Preview of RIA works and the way that a finished version will work. Also the level of support seems to suggest that this will become "The Way" to talk to a server in Silverlight.
Just cause it's worth mentioning, have some links:
http://blogs.msdn.com/brada/ Brad Abrams has an example that he is continually updating.
http://forums.silverlight.net/forums/53.aspx this is where you go to ask questions.
http://www.riaservicesblog.com/Blog/ Colin Blair knows his stuff, and he is very helpful.
I think I would not go POX ever again. If you write WCF so that the service itself is independent of the binding and binding is done in configuration files, then WCF is pretty much agnostic about transport and protocol. It can do SOAP, JSON, REST, or its own form of binary serialization. All of this is in the binding. Internally, WCF only specifies what gets exposed in terms of operation and data contracts (all defined by class, method, and property attributes). WCF gives you tremendous flexibility in this regard, with more to come in 2010.
From the Silverlight side, WCF requires that you write some plumbing code. The .NET frameowrk has the tools to build the proxy in your Silverlight project, but you must be prepared to handle all WCF responses asynchronously, and the proxy cannot catch exceptions thrown by the service.
.NET RIA Services hides all this. It uses WCF under the covers, but that is completely hidden. You don't have to write asynchronous code. You define validation once, mostly declaratively, and it works both server-side and client-side. Release 1 will be targeted for Silverlight, so you don't get the versatility to use the service elsewhere. That scope is supposed to be broadened in later releases.
I don't know enough about ADO.NET Data Services to compare. I suspect the answer would depend on whether you want to expose your data to more than just Silverlight usage.
.NET RIA Services looks like the direction I'd want to go (looking at these issues myself, with a large application in mind). The big issues for me will be implementing a very large collection of functionality in the service layer, and not being able to code directly to the data access layer (we have to be able to run on either SQL Server or Oracle).
Using WPF instead of Silverlight changes everything, depending on where your data resides. It's like the old question of Winforms vs. ASP.NET. With WPF, you're building a Windows client app, and you don't need to use any form of service-based data interface at all, unless your data access forces you into it. You'll still want to separate data and business from presentation code, using MVVM, MVC, or MVP. Other than that, you have the option to treat data access as a layer, rather than a wholy independent tier.
WCF is Microsoft's standard for service communication. I would strongly advise anyone to create a service layer using WCF Web APIs (uses WCF, but tailored specifically for REST), which is coming out this April 2012. WCF Web APIs is currently in preview mode.
Remember these rules of thumb:
- your UI will change faster than your service layer. RESTful services will be around in several years, Silverlight probably won't
- will your services ever be APIs? Well...WCF REST is the way to go
- will you mix JavaScript and Silverlight code? WCF REST will make your life easier
- will you have a mobile component (since Silverlight won't run on iOS or android)...REST is preferred.
Don't tailor to the technology, but the app as a whole.
If you want to create a Silverlight Application and you do not care about other clients, then I would choose RIA Services. It is quite painless to use and you do not need to worry how the connection from the client is made (i.e. no client side configuration necessary). RIA also generates classes for all your entities on the client and you can even share your own "server" code with the client if required (useful for enumerations or extension methods).
Remarks:
I never tried this, but if you really need you can access the RIA Service also with other clients, after all RIA Services are built on top of WCF services.
I do not quite understand Akash Kava's security concerns. You can (and have to) control security on the server-side as you would do with any other service.
For me I have a WCF service which acts as DAL and does all the CRUD operations
I just came to know regarding the new ADO.Net Data Service, just read somewhat but not actually sure when & where to use it?
Just to add more, my new project is in ASP.Net MVC, so is it wise to use ADO.NET Data Service rather than WCF service with it which will probably act somewhat like 'M'(Model) of MVC ???
First, my advice would be to write your MVC code so that it is oblivious to what the back-end data model is. Abstract away any dependencies right from the beginning.
As for deciding whether or not to use WCF, I'd suggest that you decide whether or not you'll want to reuse the data component that you write. If you have plans on using your data code in a Silverlight, WPF, or any other format, then I'd suggest sticking with WCF.
Also, remember that you can always simply wrap the ADO.NET data services with a WCF component and still enable the reuse scenario. Get the best of both worlds!
One big advantage is that with the ADO.NET Data Services, you don't have to specifically write all the services for basic CRUD operations as you may with WCF. Since ADO.NET data services basically expose those operations, you can focus more code writing and debugging on business logic.
The big advantage of WCF Data Services, and IMO it fits your need, is when your service layer is used for CRUD only. You do not have (and do not need) any business logic in it.
As Tad pointed out, the reuse is an advantage, but on the other hand, WCF Data Services will give your web app, or any consumer, a very flexible way to query data. With WCF, you'll have to write code to give the consumers the same query flexibility OData gives.
I had a experience recently. I created a service layer with WCF and in many cases, the service operations was used only to call a repository. There wasn't any rule, only query logic. The consumer was able to pass a criteria to have a result back.
The requirements changed and we realized that we could make it more simply (less code to maintain) by using WCF Data Service.
I have created an n-tier solution where I am retrieving related data from a WCF service, updating it within a Windows Forms application, and then returning the updated data via WCF to be persisted to the database. The Application, WCF Service and Database are all on different machines.
The data being retrieved consists of an object and child objects...
public Product Select(string catalogueNumber) {
return (from p in this.ProductEntities.Products.Include(#"Tracks")
where p.vcCatalogueNumber == catalogueNumber
select p).FirstOrDefault() ?? new Product();
}
The updates being applied by the client application can, as well as updating existing content, also insert additional "Track" objects.
When I receive the Product object back from the client application, I can see all of the updates correctly, however in order to save all of the changes correctly I have to jump through a few hoops...
public void Save(Product product) {
Product original = this.Select(product.vcCatalogueNumber);
if (original.EntityKey != null) {
this.ProductEntities.ApplyPropertyChanges(product.EntityKey.EntitySetName, product);
// There must be a better way to sort out the child objects...
foreach (Track track in product.Tracks.ToList()) {
if (track.EntityKey == null) {
original.Tracks.Add(track);
}
else {
this.ProductEntities.ApplyPropertyChanges(track.EntityKey.EntitySetName, track);
}
}
}
else {
this.ProductEntities.AddToProducts(product);
}
this.ProductEntities.SaveChanges();
}
Surely, there has to be an easier way to do this?
Note: I have spent the better part of the afternoon investigating the EntityBag project, but found that this has not been updated to work with EF RTM. In particular, whilst it will successfully update the existing data exceptions are thrown when mixing in new objects.
I don't have a ready-made answer for your particular scenario - but just a question: have you checked out ADO.NET Data Services (f.k.a. "Astoria") ?
They're built on top of Entity Framework, WCF's RESTful interface, and they offer a client-side experience, plus they also seem to have a decent story for not just querying, but also updating, inserting records into databases.
Could this be an option?
Check them out on MSDN, at David Hayden's blog, on Channel9, or see some of the excellent sessions at MIX08 and MIX 09
Marc
You should probably take a look at Danny Simmons' EntityBag sample.
It is designed to simplify these sorts of issues:
http://code.msdn.microsoft.com/entitybag/
As CatZ says things will be a lot easier in .NET 4.0.
One of the things we are planning on doing to help is creating a T4 template for you that generates classes for you that are capable of self-tracking, and some extra surface to make it simple for these self-tracking entities to ApplyChanges() to the context when they get back to the server tier.
Hope this helps
Cheers
Alex (PM on the Entity Framework team at Microsoft).
I see that this thread is quiet followed, so I allow myself to do a little update...
Weeeeee !
Self-Tracking entities has arrived in EF 4!
Check this out:
http://blogs.msdn.com/efdesign/archive/2009/03/24/self-tracking-entities-in-the-entity-framework.aspx
Explanation of the self-tracking mechanism by the entity framework team.
http://aleembawany.com/2009/05/17/new-features-in-entity-framework-40-v2/
Anouncement of new features in EF 4.
http://msdn.microsoft.com/en-us/magazine/ee321569.aspx
Comparison of several N-Tier patterns for disconnected entities.
Enjoy !
In Entity Framewrok 4 you can use the method "ApplyCurrentValues" to update a detached entity.
In your scenario will be something like this:
this.ProductEntities.Product.ApplyCurrentValues(product);
foreach (Track track in product.Tracks.ToList()) {
if (track.EntityKey != null)
{
//Update Entity
this.ProductEntities.Track.ApplyCurrentValues(track);
}
else
{
//New Entity
this.ProductEntities.Track.Attach(track);
}
}
I hope it will be useful
One of the limitations of Entity Framework v1.0 is Updating Entities. Unfortunately I think you are out of luck until version 2 arrives.
I'm developing and application that runs as a Windows service. There are other components which include a few WCF services, a client GUI and so on - but it is the Windows service that access the database.
So, the application is a long-running server, and I'd like to improve its performance and scalability, I was looking to improve data access among other things. I posted in another thread about second-level caching.
This post is about session management for the long-running thread that accesses the database.
Should I be using a thread-static context?
If so, is there any example of how that would be implemented.
Every one around the net who is using NHibernate seem to be heavily focussed on web-application style architectures. There seems to be a great lack of documentation / discussion for non-web app designs.
At the moment, my long running thread does this:
Call 3 or 4 DAO methods
Verify the state of the detached objects returned.
Update the state if needed.
Call a couple of DAO methods to persist the updated instances. (pass in the id of the object and the instance itself - the DAO will retrieve the object from the DB again, and set the updated values and session.SaveOrUpdate() before committing the transaction.
Sleep for 'n' seconds
Repeat all over again!
So, the following is a common pattern we use for each of the DAO methods:
Open session using sessionFactory.OpenSession()
Begin transaction
Do db work. retrieve / update etc
Commit trans
(Rollback in case of exceptions)
Finally always dispose transaction and session.Close()
This happens for every method call to a DAO class.
I suspect this is some sort of an anti-pattern the way we are doing it.
However, I'm not able to find enough direction anywhere as to how we could improve it.
Pls note, while this thread is running in the background, doing its stuff, there are requests coming in from the WCF clients each of which could make 2-3 DAO calls themselves - sometimes querying/updating the same objects the long running thread deals with.
Any ideas / suggestions / pointers to improve our design will be greatly appreciated.
If we can get some good discussion going, we could make this a community wiki, and possbily link to here from http://nhibernate.info
Krishna
There seems to be a great lack of documentation / discussion for non-web app designs.
This has also been my experience. However, the model you are following seems correct to me. You should always open a session, commit changes, then close it again.
This question is a little old now, but another technique would be to use Contextual Sessions rather than creating a new session in each DAO.
In our case, we're thinking of creating the session once per thread (for our multi-threaded win32 service), and make it available to the DAOs using either a property that returns SessionFactory.GetCurrentSession() (using the ThreadContext current session provider, so it's session-per-thread) or via DI (dependency injection - once again using ThreadContext.)
More info on GetCurrentSession and Contextual Sessions here.
You can also flush the session without actually closing it and it achieves the same thing. I do.
We've recently started using an IoC container to manage session lifecycle, as a replacement for the contextual sessions mentioned above. (More details here).
I agree, there aren't many examples for stateful apps.
I'm thinking of doing the following:
Like you I have a windows service hosting a number of WCF services. So the WCF services are the entry points.
Ultimately all my WCF services inherit from AbstractService - which handles a lot of logging and basic DB inserts/updates.
In one of the best NHibernate posts I've seen, a HttpModule does the following:
see http://www.codeproject.com/KB/architecture/NHibernateBestPractices.aspx
private void BeginTransaction(object sender, EventArgs e) {
NHibernateSessionManager.Instance.BeginTransaction();
}
private void CommitAndCloseSession(object sender, EventArgs e) {
try {
NHibernateSessionManager.Instance.CommitTransaction();
}
finally {
NHibernateSessionManager.Instance.CloseSession();
}
}
So perhaps I should do something similar in AbstractService. So effectively I'll end up with a session per service invocation. If you examine the NHib best practices article link above, you'll see that the NHibernateSessionManager should deal with everything else, as long as I open and close the session (AbstractService constructor and destructor).
Just a thought. But I'm experiencing errors because my session seems to be hanging around for too long, and I'm getting the infamous error - NHibernate.AssertionFailure: null id in entry (don't flush the Session after an exception occurs).