This is related to a previous question I asked, regarding splitting a asp.net mvc web application into two apps - one public, and one admin. Both of them would be sharing the same database of course.
With two web apps I'll have two host applications and so two seperate Nihbernate session factories. My concern is that their seperate data caches will cause all sorts of problems.
While posting this, I looked at this question, which covers a similar problem (for a different reason). I really don't want to have to set up some kind of distributed cache just for a low use admin application.
How can this be resolved? Is separating the admin section into it's own application not possible with NHibernate without drastic measures?
Thanks.
We run this successfully although some discrepancy in the data is always a problem. However, since the 2nd level cache is configurable per site, you can disable as well as turn it down for specific cache areas on your manager.
The 2nd level cache will only be used for reading, since explicit updates will be flushed down and persisted directly.
If your concern is that content on the site will be "old" once modified, some sort of trigger will be needed to instruct the site to evict the cache. NHibernate will then evict all 2nd level cache for a specific entity type if I remember it correctly.
I think your problem with concurrency will be minimal if your site vs your admin will update different entities. For example in a webshop:
Site will create orders, modify customers etc but only read products, prices and categories
Admin will modify orders, products, prices and categories but only read customers
You can however instruct NHibernate to only update modified fields/properties on your objects for entities that you are concerned about concurrency issues with dynamic-update="true" on your mapping. This won't fully solve your problem, but minimize concurrency issues.
First, you should know that NHibernate doesn't enable second-level cache by default.
So, actually you don't even need any additional steps to complete to just not to use distributed cache. Just use your "Admin" ISessionFactory and don't enable any L2 cache for that.
It could be a sort of problem inside a single App/Factory but you already solved that problem by dividing them into 2 different physical apps.
Related
Is it possible to build an ASP.NET website using EF where each customer logging in has separately stored data? We have customers demanding that their data won’t be stored in the same tables as other customers’ data.
I’ve read that EF can’t work with several databases but is it possible to switch database at runtime depending on input parameters? I have a feeling it won’t be possible since the migration features are tightly connected to the database being used, but I'm not sure.
One solution could be to have a separate website deployment and database for each customer. They’ll get separate domains to access but that’s not a problem. But this solution feels a bit clumsy if you’re having many customers, especially with deployment and future upgrades.
Am I missing some smart ways of solving this or is this a very tricky issue?
is structure (of the db) the same ?
if so you could switch connections - not w/o issues though, but should work. For details on how that should be done check the long discussion we've had here (and linked previous questions etc.)...
Code first custom connection string and migrations without using IDbContextFactory
We have done a project with around 20 tables in SQL Server, and a completed an ASP.NET project.
Recently our client told us about a new parameter called Site. As he says there are multiple sites for a project data in Application have to be different for each site. We are facing some issues now since the application is completely developed we can not update every SQL Server table and every SQL query related to Application to change according to the site parameter now we are discussing to have multiple databases for each site.
Things get worse because client says there can be around 20 sites per project. So for us it'll be very hard to manage 20 databases.
Can some one please tell us a appropriate solution for this issue?
The solution you have suggested would appear to be the correct one; use a different database per site (note: a database server can host all 20 databases easily depending on the transaction volume).
Explanation:
What you need is to separate the data per site; this can either be done by adding a site identifier to the tabular data or by making sure sites do not share a datastore; the latter is in this case the easiest and most cost effective solution.
Note that "maintaining a database" is not as hard as you make it sound; in my opinion the volume of the data and transactions to manage and the number of manual corrections to make are the key factors in cost of maintenance...
I've been down this road in the past before and what we did was created a Site table, and then the objects that a site owned, we added a foreign key relationship back to the Site table.
In our case we only had three or four objects that a site owned, so we only had to modify 4 tables. Then the relationship from there down would still work and no modifications would be needed.
I would not go the route of a database per site, it will become a maintenance nightmare if you have to make database changes in the future or if you want to pull reports across the system as a whole
I have three different applications, they all share the ASP.NET membership aspect of the database and almost definitely they won't share anything else.
Should I have a separate database for each of the applications, or would one suffice?
All the application tables are prefixed, so that wouldn't be a problem in integration. Although I was wondering if there would be any performance issues, or if having all three applications share the same database would be some kind of grave mistake.
The applications in question are three web applications, the "main site", a forum and a bug tracker. I'm wondering if this is viable because integration could be easier if I had a single database. For instance, the bug tracker registers asp.net membership tables in it's db connection, and it even creates an "admin" user, where the db that is actually supposed to be holding the membership tables would be the "main site" one.
Update: I added a bounty to this question since the answers seem to have pretty split opinions about whether I should or not use multiple databases for different applications that share only membership providers.
Separate apps = separate databases - unless you have to "squeeze" everything into a single DB (e.g. on a shared web hoster).
Separate databases can be backed up (and restored!) separately.
Separate databases can be distributed onto other servers when needed.
Separate databases can be tweaked individually.
I have always found it would be better to have more databases so that it is easier to:
Migrate to more servers if needed
Manage security / access easier
Easier (and Faster) restores and backups
I would actually go with four databases. A Membership database, and then one for each application (if the membership is truly shared). This will allow you to lock security across applications as well.
Looking at your question closer... You say that the data would "likely not be shared"... will a lot of your queries be joining tables with the membership? If so, might be easier if they are in the same database. However if you are going with a more entity based approach, I would think you would still be better with multiple databases. You might even want to look at something like an LDAP database or some other type of caching for your membership database to speed things up.
You should use the same database unless you have a current need to place them in separate databases - HOWEVER where possible you should architect your system so that you could move the data into a separate database should the need arise.
In practise this means that you should keep SQL procedures working the smallest amount of data possible - i.e. Don't have multi-step stored procs which do lots of separate actions. Have separate usps and call each from code.
Reasons to use separate databases:
1) Unrelated data - Group data that is interrelated - andonce databases get beyond a certain complexity, look to separate out blocks of related data into separate databases in order to simplify.
2) Data that is of either higher importance (e.g. Personal Details) should be separated to allow for greater security measures: e.g. screening this data from developers
3) or lower importance (e.g. Logging Info) - this probably does not need backing up - and if it's particularly volumous, you probably don't want it increasing the time taken to back up the main site database.
4) Used by applications living on different servers at different locations. Quite obviously you want to site data as close as possible to the consuming application.
Without really knowing the size and scale of your system, difficult to give full opinion, if it's just your own site, one db may work for now - if it's commercial then i'd have 4 dbs from the word go: Membership details, Forum, Bug Tracker and MainSite related stuff.
Thus in code you would have a Membership manager which only talks to the Membership db, A BugManager, A ForumManager and anything else will only talk to the MainSite db. I can't think of any reason you'd need any of these databases talking to each other.
Just my inclination: although the three apps might not share much (not yet, anyway: but what happens when a forum post wants to reference a bug report?), they all belong to the same "system," so to speak.
I would definitely put all of the tables in just one database.
In my opinion , it is better to split the database for increased flexibility, security, efficiency, and scalability.
In future if there is any addition of requirement (you never know) which is common to all the three applications , it might be a little difficult to maintain.
For example: User login /audit trace for your 3 applications.
It may sound like I'm wandering a bit, but have you taken into account another possibility, that is separating all the authentication/membership functionality into an application itself?
From your description it seems you may add another application in the future. It would start to look like a network of sites, much like 37signals web apps, Google web apps or MSN web apps.
And thus, you may go for a kind of Single-Sign-On / Connect service. This one single application may offer authentication methods via web-services or any other mechanisms, it will have its own DB for you to tweak, modify, backup and move without affecting the other apps. I myself have found this situation many times and thus I love how easy is to share your Google or Facebook login among applications.
Perhaps I'm seeing it from a little higher perspective than yours, sorry if it's the case. If this is not an option, you may keep 4 databases: 1 for each application and 1 for the membership provider, which has its own connectionstring most of the time.
Of course it depends on the size of your applications' footprint on DB-level. 10 tables per app is OK, 150 tables per app would make the DB a little ugly to us, that being a personal preference.
Good luck with whatever option you choose.
The membership framework allows for partitioning across multiple applications, so you probably should have the following configuration:
Membership Database
Application 1 Database
Application 2 Database
Application 3 Database
Then, in each of the application databases, create synonyms that point to the membership database's tables for when you need to write your own queries that access both application data and membership data. Synonyms are easy to maintain and allow you change where the database is without changing any dependencies on those tables as the synonym names don't change.
Your application configuration in Web.config will determine how the data is partitioned in the membership database as you specify an ApplicationName that should be different for each app.
There are certain tables that get called often but updated rarely. One of these tables is Departments. So to save DB trips, I think it is ok to cache this table taking into consideration that the table has very small size. However, once you cached it an issue of keeping the table data fresh occurs. So what is the best way to determine that the table is dirty and therefore requires a reload and how that code should be invoked. I look for solution that will be scalable. So updating the cache on single right after inserting will not resolve the issue. If one machine inserted the record all other on the farm should get notified to reload the cache. I was thinking for calling corresponding web service from T-SQL but don't really like the idea of consuming recourses on sql server. So what are the best practices to resolve this type of problems.
Thanks in advance
Eddy
There are some great distributed caching frameworks out there. Have a look at NCache and Velocity. NCache has some great features for keeping the cached data in sync between different cache nodes as well as the underlying database. But it comes at a price.
Have you tried using sql dependencies or cache dependencies? The library will pole the database every so often to see if the data has changed. An alternative is to use cache dependencies too. You can have a master cache object and have child caches depend on it. so if the master cache change the child caches will be updated.
Edit:
If the above is not a solution you can easily use memcached.net -- wikipedia. Geared toward large sites but it is a solution for your problem.
Here is an article that describes the thinking around setting up a cache.
http://www.javaworld.com/javaworld/jw-07-2001/jw-0720-cache.html?page=1
Generally speaking objects in a cache have lifetimes and when the lifetime expires they are re-fetched from the database. If the data is not so important this eventual consistency allows for a mixture of performance and accuracy of presented information.
Other cache tools add in additional techniques to keep data more accurate i.e. if a particular object is known to be updated then repopulate after the update command is executed.
There are multiple values I have been storing in ASP.NET configSections sections for each "module". I have been wondering if they even belong in these files at all.
The background stands at: These are multiple instances of the web application deployed. All use the same database but have their own settings.
I'm sure that differences between development and production go in the config files. Some of the values I know should include: connection strings, providers to use, setting debug, etc.
I have factored out all the common pieces in to classes with their own rules and methods. The pieces left are miscellaneous settings for each module in each site. Some of the options I'm unsure of include:
For ModuleA, Show/Hide Option
For ModuleB, What is the terminology to be used for this field
For ModuleC, Allow end user to perform X action
Mmm these sounds like things that you might want be able to change at runtime for your application without having to modify the app.config. One rule of thumb I like to follow is that anything in the config should be for the deployment or server configuration. In this case your settings appear to be modifying the application behaviour and so I would probably move them into the DB if it is not alot of effort.
ModuleA and ModuleC sound like they may be user profile information. If they're not dynamic by user, but you could add later functionality, then maybe move them to a DB.
I've written apps where ModuleB would have been put in a DB also. Things like form labels, etc. can easily go in a DB. If, at a later date, someone decides to add or remove colons to all form labels, that's a pretty easy thing to do if all of the text is stored in a DB.
Consider the situation when you need to edit one of the values.
If the value is in web.config, saving the change to that file will cause the app to recycle, inconveniently throwing out current users. Not so much of a problem if your app is on an intranet only used during business hours (though you could get an angry call from the guy who stayed to work late). But potentially a problem on a public website with international users.
If the value is in a database, it will have no impact on the app's processing in that way.
Either way, consider whether the values are cached in the app's RAM (web.config is). Are the database values in an Application variable, or in Cache? If so, you may not know when the change will occur. Unless you want to restart the app.
And, what different access and permissions would the appropriate admins need to make the changes? Someone would have to have access to the web server(s) to change web.config, or to the database (and table) to change that.
A few questions: Why do you use the same DB for multiple instances of the application, and how will that effect maintanence?
In the future will it be an option to split the db in order to improve performance? Does the config model support that change better then the DB based one?
In other words, you will have to consider a lot variables in order to answer your question :-)