Data component for multiple identical databases in a SOA

Hello,

I have 10 databases that are identical, on 1 database server (sql server).
The same database component is used to access all the databases.
When the client application start the user define which database to use from a menu, and all the session use the same database until the client is closed.

At the moment the database component is coupled with the client. When the client start, it set a Static field on the database component with the name of the database to use.

Now the company wants a SOA architecture with the database component in a separate server, without state, client will comunicate by web services or WCF.

Question: How can client define the database to use?. I don't want to modify every method of the data component to pass the database name as parameter.

Thanks.

[845 byte] By [Heraclito] at [2007-12-31]
# 1
One trick we did in a similar situation was to use the .NET equivalent of thread-local storage. The service receiver sticks the DB info into a named slot using System.Runtime.Remoting.Messaging.CallContext.SetData(string s, object o). The apps component retrieves it using object o=GetData(string s). The docs say you shouldn't use these functions directly in your code, but we haven't run into any issues yet.
erikj at 2007-9-6 > top of Msdn Tech,Architecture,Architecture General...
# 2

That would work for remoting only?

I need a solution for web services or wcf(prefered), I was thinking in soap headers.

msdn help on Soapheader class says:
"SOAP headers offer a method for passing data to and from an XML Web service method if the data is not directly related to the XML Web service method's primary functionality."
That exactly my situation. I doesn't make sens to modify operations definition to include information not exactly related to the method implementation and could change independently of the method implementation.

But I'm not sure if this is the best practice to solve this kind of problems. It seems to me that there isn't an easy way to use soap headers on wcf.

Thanks.

Heraclito at 2007-9-6 > top of Msdn Tech,Architecture,Architecture General...
# 3

Hi Heraclito;

As I understand from your initial post that "When the client application start the user define which database to use from a menu, and all the session use the same database until the client is closed.". So, do you maintain sessions on the server side? If yes, it would be simple when the client initialize the connection to the server, client pass the DB name and the server maintains it. your DB component read such information from the client session. This is pretty common, so I recommend it.

I'm not sure if you have other technical requirements or technical constraints that prevent you from using such technique. Let us know if you have such constraints or technical requirements.

I hope you find this useful,

AhmedNagy at 2007-9-6 > top of Msdn Tech,Architecture,Architecture General...
# 4
I may have misunderstood the situation. In out case IIS received a SOAP message, our framework resolved the host/path parts of the URL to figure out which database to call (our client did not send this info), and we put this info into a thread-local storage using SetData(). The application component gets invoked, which also used our framework to execute database commands with an object (I think) called DBAccess. Our DBAccess class used GetData() to get the DB connection info and the current transaction context.

It was a hack to get around the fact that the app components did not have any knowledge of the database connection info. We did not use .NET remoting.

But if your client is going to send context info, I think SOAP headers are a fine way to do it -- it's what they are there for. We used SOAP headers quite a bit to send transaction URLs (TIPUrl) and identity information between server instances.

erikj at 2007-9-6 > top of Msdn Tech,Architecture,Architecture General...
# 5

Hi erikj,

I would be interested in you code if you used WCF or WSE to manipulate soap headers for carrying transactiona and identity information.

Can you share it here (main parts of it).It wold be very beneficial as i also have to implement somewhat same as what you did

Regards

thompson3 at 2007-9-6 > top of Msdn Tech,Architecture,Architecture General...
# 6

I think you should

1. expose an interface once to set your database using the clients' session ID.

2. Use MS patterns and practices Data Access Block and supply the "createdatabase" method with the required database as a parameter.

This way the parameter will be passed down all the way to the data access layer and the data access application blocks will handle the databse connection for you.

LivetoCodeCodetoLive! at 2007-9-6 > top of Msdn Tech,Architecture,Architecture General...
# 7

You've got a few suggestions on how to solve the database affinity problem so I won't talk about that

I do want to to comment on "now my company wants a SOA architecture..."

having a client tell a service what database to use is not realy SOA - There is nothing SOA about what you descrube.It sound like you are just using web-services technology but you are implementing the same RPC client/server solution you had before.

If you are really looking into building SOA than the underlying solution used in the service is an implementation detail you don't want your clients to be aware of. What's the business meaning of each database ? this the information that you want the client to pass to the server

Arnon

ArnonRotemGalOz at 2007-9-6 > top of Msdn Tech,Architecture,Architecture General...
# 8

Ahmend, I'm Sorry I didn't clarify. I was thinking in a client side session. Clients are web server for web users and windows forms application. The client knows what dabase to use because the user chose it in the first form from a list. Web clients put this data in the session collection, windows form clients in a static field. The problem is how to pass this information to the data component that is a stateless service running in another machine.

LiveToCode, I'll check that library to look for ideas.

erikj, i think soap header is the way to go, but wcf doesn't support them nicely, that's sad.

Arnon, When the user start the client application it receive a list of companies, the user have to chose one to work with. Every company have a ID number, that's the number the client must pass to the data component. The data component have a table with IDs and database name. Looks better, or still not a SOA?

Heraclito at 2007-9-6 > top of Msdn Tech,Architecture,Architecture General...
# 9

erikj wrote:
One trick we did in a similar situation was to use the .NET equivalent of thread-local storage. The service receiver sticks the DB info into a named slot using System.Runtime.Remoting.Messaging.CallContext.SetData(string s, object o). The apps component retrieves it using object o=GetData(string s). The docs say you shouldn't use these functions directly in your code, but we haven't run into any issues yet.

erik - you can access thread local storage now very easily now .Net using ThreadStaticAttribute

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemThreadStaticAttributeClassTopic.asp

Ollie Riches

OllieRiches at 2007-9-6 > top of Msdn Tech,Architecture,Architecture General...
# 10

Heraclito, I am absolutely agree with Ahmend, if you want to follow an SOA approach for your architecture you want to avoid the client of the server having to pass any kind of information that affects how the internal infastructure (database) is configured and used.

I don't understand why your backend database storage has been designed as a seperate database per client\company- now you might have valid reasons for this but for me this hints at how you should also think about designing your services, e.g. if you have a database per client\company for a scailibilty and performance reasons then surely these needs to be also considered when designing the services.

If you have a limited number clients\companies i would consider an instance of the service per client\company, now this can become a maintainence issue but if you use automated build processes and develop an installer per client\company required then the overhead can be reduced through build automation.

Ollie Riches

OllieRiches at 2007-9-6 > top of Msdn Tech,Architecture,Architecture General...
# 11
Ollie Riches wrote:

If you have a limited number clients\companies i would consider an instance of the service per client\company, now this can become a maintainence issue but if you use automated build processes and develop an installer per client\company required then the overhead can be reduced through build automation.

Ollie Riches

I basically agree with Ollie - but you don't have to use multiple instances instead you can create multiple contracts and add an Edge component that will work against a single instalce of the service . The Edge componetns will handle notifying the service which databse to use etc. (see http://www.rgoarchitects.com/Files/SOAPatterns/EdgeComponent.pdf for more information on the Edge Component Pattern)

Arnon

ArnonRotemGalOz at 2007-9-6 > top of Msdn Tech,Architecture,Architecture General...
# 12

Nice article and an interesting pattern, we use something similiar - a 'service adapter' layer that sits between our 'service contract' layer & our frameworks 'business logic' layer, this allows us to put any user context based implementation in a defined location that does not affect either the service contract(s) or the generic business logic.

There are nice set of diagrams in the following article:

http://msdn.microsoft.com/msdnmag/issues/06/12/ServiceStation/

OllieRiches at 2007-9-6 > top of Msdn Tech,Architecture,Architecture General...
# 13

Hi Ollie

I am glad to hear that - as you may have noticed it, and the other patterns I've published, are still in draft status so any imput is welcomed.

Arnon

ArnonRotemGalOz at 2007-9-6 > top of Msdn Tech,Architecture,Architecture General...