emails sent three times asp.net website - c#

I am working on a e-commerce website and there is an issue which we are trying to solve.
After customer completed order she is receiving three emails (all of them same) instead of one.
The website is running on three servers and we think that's the problem because using only one server brings one email delivered to the customer.
I would like to know what we should do so the user will receive only one email instead of three and we will still run the website on three servers.
Thanks in advance, Laziale

You cannot count on locking hints in the database for this. A hint is just a hint; there's no guarantee that the locking will happen as you expect (assuming this is SQL Server). In general, a relational database is just that, a database. A table is not a queuing mechanism and you will always have problems if you try to use it that way.
Nonetheless, in order to implement a different solution, we have to determine if a single record is being added to the "queue" or if three records are being added. If it is the first, and only a single record is added but three emails are sent out then the solution is simple. Instead of using a database table as your queue, use Microsoft Message Queues (MSMQ) instead. They are part of Windows Server and have been since at least 2003, maybe even all the way back to 2000. They will provide you with an actual queue specifically designed for what you're trying to accomplish.
If there are three actual records being added to the "queue" table in the database that means there is a code problem. Even with three Web servers in the load balancer, the fact remains that a single order submission only happens on one of those servers. The business logic that places the email notification in the queue could not come from more than one server because the request only originates from one server.
I would check the table first and determine if there are multiple records being added. If not, change the implementation to use MSMQ. If so, check your code to see why more than one record is being added in the request.

Related

Best way to create email database for multiple users

So here's what I'm trying to do.
I'm building an app using c# and MySQL as it's database. The database should basically be able to store inbox, sent mail, drafts, spam and trash typically.
Now here's the issue. This app is supposed to support multiple users. Meaning each user is supposed to see their own email's. Typically this would suggest that I must create a new schema for every new user, anme it accordingly and create tables inside it for inbox, sent, drafts etc.
Yes, it would be possible I suppose but assuming I may have a thousand user's... That's gonna make database management tedious among other issues that may arise.
Question here is would there be a more organised way / method of doing this? Preferably one that would make management or coding for it easier.
Appologies to be so broad. This is for a school project.
This app is supposed to support multiple users.
That basically means you need a table Users and every table supporting multiple users needs a column where you store the Users Primary Key. That way you can have a single table and have the data of multiple users in it.

How Does One Fill a Typed DataSet, Keep it Synchronized, and Receive Updates When the Data Changes?

So I'm developing an application that works as sort of a "sidekick" to a large proprietary application which I do not have the source code for nor the rights to modify. The proprietary application does store all of its data in a Microsoft SQL database (version 2008 R2 or higher, I believe), however, and I have a good idea what the data represents. What I need my application to do is to constantly monitor the data as it is being added, updated, and deleted, and then act on the data automatically (such as raising alerts).
The issue is figuring out the best approach to receiving changes made to the database by the other application as they're happening, because I don't wanna miss a beat.
Here is what I have done so far:
LINQ to SQL: As far as I know, each time I run a query, I receive a new set of data, but I do not get the ability to receive the changes only or be notified of changes.
Typed DataSet using DataSet.Load:
using (IDataReader reader = dataSetInstance.CreateDataReader())
{
dataSetInstance.Load(reader, LoadOption.OverwriteChanges, dataSetInstance.Table1, dataSetInstance.Table2, dataSetInstance.Table3);
}
This didn't work out too well when I did it. dataSetInstance only contained a set of unfilled tables after calling the Load method. I was hoping to call dataSetInstance.GetChanges and dataSetInstance.AcceptChanges at regular intervals after the first call to dataSetInstance.Load to get only the changes. Am I doing it wrong?
Typed DataSet with tables filled individually using their associated table adapters:
using (Table1TableAdapter adapter = new Table1TableAdapter())
{
adapter.Fill(dataSetInstance.Table1);
}
using (Table2TableAdapter adapter = new Table2TableAdapter())
{
adapter.Fill(dataSetInstance.Table2);
}
using (Table3TableAdapter adapter = new Table3TableAdapter())
{
adapter.Fill(dataSetInstance.Table3);
}
Of course, the problem is that there are actually way more than 3 tables which can add up to quite a lot of repetitive code (and maintenance work), but the real problem is that I will not receive any change notifications since I'm not using the Load/AcceptChanges methods (according to the documentation).
Row retrieval by date/time field: This was something I started work on, but something I stopped after observing the other application modify fields in the rows after creating them. Consider this:
There is a row with a time stamp of a transaction and a boolean field that specifies if the transaction was canceled later on. If it is canceled, the other application simply goes back to that row and toggles the value. The time stamp remains the same, and my application will never know of the news. There is no statute of limitations; the other application can change this field any time in the future.
By the way, I should mention that this other application does not implement any constraints within the database such as foreign and primary keys. I believe I read somewhere in the documentation that for row update events and such to fire on the typed DataTable classes, some sort of primary key is needed.
There must be some way to do this!!!
Have you considered SQL Server Query Notifications? This uses SQL Server Service Broker under the covers.
SqlDependency is the C# class to look at.
Using SqlDependency in a Windows Application (.NET Framework 2.0 example: should be very similar to later versions.)
SqlDependency in an ASP.NET Application
I’d consider solving this at SQL Server level by implementing auditing triggers or SQL Server traces.
Triggers – idea is to add triggers to all tables you want to monitor. Triggers will catch all changes and store the data in some other “history” table. Once this is setup all your application needs to do is to read from these tables.
Check this for more details Creating audit triggers in SQL Server
Traces – you can setup SQL Server traces that will store all info in trace files and then your app can parse trace files and see what’s going on.
There appears to be no silver bullet to the problem given the conditions, but anything is better than polling the database for changes every minute. What I will probably do now is take Mitch Wheat's suggestion and work from there:
Some tables have rows that are highly likely to change. A recent purchase, for example, is more likely to be cancelled than one from 7 days ago, or 6 months ago, or in the case of 1 year—probably never. The application will only need to monitor queries restricted to a certain time range. Older (in terms of creation time) rows will simply be refreshed at a much slower rate and without prompting from SQL Server query notifications. The application is going to have to tolerate some stale data in order to not needlessly pull entire tables from the database every minute.
For tables without chronological information, the application will have to receive notifications for queries on conditions that are important or have to be acted on right away such as WHERE Quantity < 0.
Some more clever approaches will need to be taken for the rest of the tables. Some tables are never updated nor their rows deleted, but they will gain new rows whenever some other table's rows changes. For example: every time the NumberOfPeople value changes for a row in table Room, another row is added to one of the tables CheckIn or CheckOut.
A lot more code needs to be written, but the application is probably going to be doing a lot less unnecessary work when it's running.

Performance related issue

There is following scenario:
I am working on one telecom based project which generates price for provided site details input.
Input is passed in the form of Excel sheet and corresponding output is displayed in gridview.
Output grid contains two dropdownlists which is populated based on site details.
That means there is two dropdown in every row of gridview which is filled by hitting database
At present this tool is working fine for 200 sites,but now client wants to pass 10,000 sites from excel sheet as a input.
It will be very tedious job to hit database for 10,000 sites and it will slowdown the performance of the system.
I am using asp.net 3.5 using C# and database sql server 2008
Does anybody have solution for the best possible way to do this task?
Scalability is your key here.
You should utilize load balancing where possible, if you could make some process asynchronous then do it - using something like ActiveMQ or RabbitMQ this will stop UI Hangs.
Also consider having clustered DB Servers.
Your goal should always be to give the user feedback ASAP (async feedback), Guarantee work processing (Queue/Message system), handle lots of users (Load balancing).
Theres also a lot to be said for code optimization, have a look at your code and see if theres any areas you can "trim the fat" to speed things up.

Detached Smart Client Syncing

I am working on an application at the minute that will originally be just installed on a client machine with a lightweight database (may SqlLite).
After a while I want to add a web version of the same piece of software and with this the smart client will then be able to sync with the online version.
Has anyone done anything similar, I am looking to know:
What is the best way of syncing, are there patterns around it?
Are there any frameworks out there to handle syncing?
Is there any gotcha's I should be aware of from the start (maybe security concurrency)?
What would be the best way to architect this?
Thansk in advance...
So, Microsofts Sync Framework will help with this. Introduction
Couple of issues stand right out at the beginning.
If you are going to have the data exisit on the client first, then sync to a server at some point later, you need to think about what happens when a number of clients all sync to the server, esp. around conflict resolution.
There are events that get raised on the server side to idetify when a conflict occurs, but you need to decide who wins. (one on server, one from incoming client). Depending on wht you choose to do here, the second sync is likely to modify the client data.
Think carefully about what to sync. If its a contacvts database, is it good enough to have just the client name and telephone number sync, or do you need to whole contact history as well?
Think in terms of syncing a table, using rows where the key is all the same value. Even if this is a constructed table with triggers etc. This makes the framework sync a much simpler process and less prone to errors (tables needed to be synched in different orders).
If its an invoicing program, maybe an upload only table of orders is needed, with all the assoiciated invoice, history, reporting tables etc being updated on the server, rather than updating them on the client and syncing multiple tables....

Data-Driven Websites for Very Small Businesses

I have a client who has a product-based website with hundreds of static product pages that are generated by Microsoft Access reports and pushed up to the ISP via FTP (it is an old design). We are thinking about getting a little more sophisticated and creating a data-driven website, probably using ASP.NET MVC.
Here's my question. Since this is a very small business (a handful of employees), I'd like to avoid enterprise patterns like web services if I can. How does one push updated product information to the website, batch-style? In a SQL Server environment, you can't just push up a new copy of the database, can you?
Clarification: The client already has a system at his facility where he keeps all of his product information and specifications. I would like to refresh the database at the ISP with this information.
You don't mention what exactly the data source is, but the implication is that it's not already in SQL Server. If that's the case, have a look at SSIS.
If the source data is in SQL Server, then I think you'd want to be looking at either transactional replication or log shipping to sync the two databases.
If you are modernizing, and it is a handful of employees, why would you push the product info out batch style?
I don't know exactly what you mean by "data driven", but why not allow the ASP.NET app to query the SQL Server product catalog database directly? Why generate static pages at all?
UPDATE: ok, I see, the real question is, how to update the SQL database running at the ISP.
You create an admin panel so the client can edit the data directly on the server. It is perfectly reasonable to have the client keep all their records on the server as long as the server is backed up nightly. Many cloud and virtual services offer easy ways to do replicated backups.
The additional benefit of this model is that more than one user can be adding or updating records at a time, making the workforce a lot more scalable. Likewise, the users can log in from anywhere they have a web browser to add new records, fix mistakes made in old records, etc.
EDIT: This approach assumes you can convince the client to abandon their current data entry system in favor of a centralized web-based management panel. Even if this isn't the case, the SQL database can be hosted on the server and the client's application could be made to talk to that so you're only ever using one database. From the sounds of it, it's a set of Access forms and macros which you should have source access to.
Assuming that there is no way to sync the data directly between your legacy system DB (is it in Access, or is Access just running the reports) and the SQL Server DB on the website (I'm not aware of any):
The problem with "pushing" the data directly into the SQL server will be that "old" (already in the DB) records won't be updated, but instead removed and then recreated. This is a big problem with foreign keys. Plus, I really don't like the idea of giving the client any access to the db at all.
So considering that, I find that the best is to write a relatively simple page that takes an uploaded file and updates the database. The file will likely be CSV, possibly XML. After a few iterations of writing these pages over the years, here's what I've come up with:
Show file upload box.
On next page load, save file to temp location
Loop through each line (element in XML) and validate all the data. Foreign keys, especially, but also business validations. You can also validate that the header row exists, etc. Don't update the database.
3a. If invalid data exists, save an error message to an array
At the end of the looping, show the view.
4a. If there were errors, show the list of error messages and tell them to re-upload the file.
4b. If there were no errors, create a link that has the file location from #2 and a confirmation flag
After the file location and confirm flag have been submitted run the loop in #3 again, but there's an if (confirmed) {} statement that actually makes the updates to the db.
EDIT: I saw your other post. One of the assumptions I made is that the databases won't be the same. ie, the legacy app will have a table or two. Maybe just products. But the new app will have orders, products, categories, etc, etc. This will complicate "just uploading the file".
Why do you need to push anything?
You just need to create a product management portion of the webpage and a secondly a public facing portion of the webpage. Both portions would touch the same SqlServer database.
.Net has the ability to monitor a database and check for updates. then you can run a query to [push] the data elsewhere.
or use sql to push the data with a trigger on the table(s) in question.
Is this what you were looking for?
You can try Dynamic Data Web Application.
You should have a service that regularly updates the data in the target DB. It will probably run on your source data machine (where the Access-DB is)
The service can use SSIS or ADO.NET to write the data. You can do this over the web, because you have access via TCP/IP to the server I assume.
Please check when the updates are done and how long it takes. If you can do the updates during the night you are fine. If not you should check, if you can still access the web during the import. That is sometimes not the case.
Use wget to push the new data file to the mvc app and once the data is received by the action, the mvc app invokes the processing/importing of the data (maybe in a worker process if you dont want long requests).

Categories