views:

240

answers:

3

So I have a challenge to build a site that people online can use to interact with organizations.: http://stackoverflow.com/questions/1691058/asp-net-mvc-customer-application

One of the requirements is financial processing and accounting.

I'm very comfortable using SQL Transactions and stored procedures to do this; i.e. CreateCustomer also creates an entity, and an account record. We have a stored procedure to do this, that does a begin transaction, creates some setup records we need, then does a commit. I'm not seeing a good way to do this with an ORM, and after reading some great blog articles I'm starting to wonder if I'm going down the wrong path.

Part of the complexity here is the data itself:

  1. I'm querying x databases (one per existing customer) to get some of my data, though my app has its own data store as well. I need to query the x databases, run stored procedures on the x databases, and also to my own datastore.

  2. I'm not seeing strong support for things like stored procedures and thereby transactions, though it does seem to be present.

Maybe I'm just trying to make my app a nail here, cause the MVC hammer is sooo shiny. I'm plenty comfortable with raw ADO.NET of course, but I'm in love with the expressive feel to writing Linq code in C# and I'd rather not give up on it.

Down to the question:

Is this a bad idea? Should I try to use Linq / Entity Framework, or something like nHibernate... and stick with the ORM pattern or should I trash it and use raw ADO.NET data access?

Edit: a note on scale; from a queries per second standpoint this app is not "huge". But, from a data complexity perspective, it does need to query against 50+ databases (all identical, or close to it) to read data from an external application and publish data back to that application. ORM feels right when dealing with "my" data store, but feels very wrong for accessing the data from the external application.

+1  A: 

From a certain size (number of databases) up, you have to change the paradigm. Are you at that size?

When you deploy what ultimately is a distributed application and yet try to controll it as an ordinary local application you are going to run into a set of fundamental issues around availability, scalability and correctness. If you use concepts like 'distributed transactions', 'linked servers' and 'ORM', your are down the wrong path. True distributed applications will use terms like 'message', 'queue' and and 'service'. Terms like Linq, EF, nHibernate are all fine and good, but none will bring you anything extra from what a simple Transact-SQL SELECT statement brings. In other words, if a SELECT solves your issues, then the client side various ORM will work. If not, they won't add any miraculos value.

I recommend you go over the slides on the SQLCAT: High Performance Distributed Applications in Real World Deployments which explain how a site like MySpace manages to read and write into a store of nearly 500 servers and thousands of databases.

Ultimately what you need to internalize is this: one database can have 95% availability (uptime and acceptable service response time). A system consiting of 10 databases with 95% availability has 59% availability. And a system of 100 databases each with 99.5% availability has 60% availability. 1000 databases with 99.95% availability (5 min downtime per week) have 60% availability. And this is for an ideal situation. In reality there is always a snowball effect caused by resource consumption (eg. threads blocked on trying to access an unavailable or slow resource) that makes things far worse.

This means that one cannot write a large distributed system relying on synchronous, tightly coupled operatiosn and transactions. Is simply impossible. You always rely on asynchronous operations (usually messaging and queues), which is something completely different from your run-of-the-mill database application.

Remus Rusanu
Great answer, thanks Remus. I've made extensive use of ActiveMQ before, actually so I'm right at home with queues. The scale of this app isn't too huge from a qps standpoint; but the info we are moving does have to be guaranteed.
Kyle Hodgson
Perhaps this article can add some value: http://rusanu.com/2009/08/05/asynchronous-procedure-execution . If you're familiar with ActiveMQ then you'll understand my point in the link about the need of *reliable* delivery in terms of ACID commits in the presence of HA failover, backup/restore etc.
Remus Rusanu
BTW, I do see value in using async queue based workflow even wheneverything happens in one single database, no remote delivery whatsoever. But in this paradigm there is very little 'bread and butter' left for the ASP.Net MVC and its the shiny LINQs, besides a top-notch presentation layer...
Remus Rusanu
It also means I have to start by creating my own async data layer, a task I was hoping to do later. :D
Kyle Hodgson
I which there were more reponses, this is an interesting topic I'm eagger to hear opinions on...
Remus Rusanu
Hi Remus - we did end up using EF1 for the ORM of our ASP.NET MVC website, but we built WCF based services for the transaction processing and for integrating data from the external websites. We were somewhat forced to do this as we realized that a lot of the environments we needed to support were in completely different data centers, which forced the issue.
Kyle Hodgson
Did you use the queued bindings for WCF, or the synchronous ones (http, tcp)?
Remus Rusanu
+1  A: 

use TransactionScope object available in System.Transaction.

this. __curious_geek
OK ... do you mean "stick with MVC but use TransactionScope to call stored procedures that have BEGIN TRANSACTION / ROLLBACK / COMMIT statements, in raw ADO.NET with no ORM?"
Kyle Hodgson
TransactionScope uses Microsoft Distributed Transaction Co-ordinator which gives you transaction support beyond Database operations. It also supports Disk I/O wrapped within transactions. It's a prime candidate for multi-database transactions.
this. __curious_geek
A: 

What I have chosen is to use Entity Framework to allow access to the application's main data store, and create a custom DAL for access to external application data and for access to stored procedures within the application.

Here's hoping Entity Framework 4.0 fixes the issue. For now, I'm using the concept listed here.

http://social.msdn.microsoft.com/forums/en-US/adodotnetentityframework/thread/44a0a7c2-7c1b-43bc-98e0-4d072b94b2ab/

Kyle Hodgson