I have a program in which it insert a raw in a table after certain operations. I wan to call a web service in code behind to do some special tasks by the using of info that there is in the inserted row.
How I can do that?
Is it good idea to invoke this web service from a stored procedure or not? What are the other options?
More Details: Actually, I have an operation in my web application that take a long time to be completed and it is seriously time consuming operation. I don't want client wait until this process finish. That is why I decide write a web service to do this process in the background.
Therefore, I think it may be a good idea that when client request receive I insert his request in a table and call a web service to handle it. Moreover, I do not want to wait until web service return the result, so I will aware client from its result through the report. I do not know what is the best solution to handle it.
I usually keep myself far away from table triggers(it sounds like you're about to use an on insert trigger for a table).
I don't know your specific situation but you could either :
Call the webservice before or after you call the stored procedure, this way the data layer(stored proc) only handles data and nothing more. You're logical layer will handle the logic of calling an extra webservice.
Write a service that will periodicly read a table and notify the webservice of the latest modifications. More messy but it resembles more the effect you're trying to achieve.
There are probably more solutions but i'd need more information on what it exactly is you're doing. Right now it's kinda vague :)
It is never a good idea to call webservice from Stored procs or other DB objects. You can call it from your code, just after you execute the insert and commit it.
The problem it sounds like is that you cannot guarantee that the web service will be called unless you call it before committing the transaction. However, it sounds like the web service needs to be called after commit. In this case, it sounds like you should use a message queue. You could either build one in your database or you could use one off the shelf (http://aws.amazon.com/sqs/ or http://www.windowsazure.com/en-us/home/features/messaging/).
The steps would be:
Insert message into queue (after this is success you can return the call, depending on what your contract with the caller is)
Read message
Insert into table
Call web service
Delete message
The downside is that you will need to make the operations (inserting into the table and calling the web service) idempotent.
Related
I have a requirement where third party software running on a desktop will write to a local database and I need to send some of that information to a remote web service. I don't have any control over the thirdparty software that is doing the insert but I can read the database.
My approach is to have a windows service check the local table every second for an insert, if there is an insert send the webservice request. I don't like checking every second but this whole process needs to happen in a short amount of time after the insert. Is there a better way to go about this? Some kind of listener? I don't think I can use triggers.
This will be .NET and SQL Server if that matters.
Try using the SQLDependency class. Implement the onChange method of the class to handle your processing. The following article describes the process of configuring your environment and has some sample code for this.
http://www.codeproject.com/Articles/144344/Query-Notification-using-SqlDependency-and-SqlCach
I'm very new at WCF (and .NET in general), so I apologize if this is common knowledge.
I'm designing a WCF solution (currently using Entity Framework to access the database). I want to grab a (possibly very large) set of data from the database, and return it to the client, but I don't want to serialize the entire set of data over the wire all at once, due to performance concerns.
I'd like to operation to return some sort of object to the client that represents the resulting data and I'd like to deal with that data on the client, being able to navigate through it backwards and forwards and retrieve the actual data over the wire as needed.
I don't want to write a lot client code to individually find out what rows meet my search criteria, then make separate calls to get each record if I can help it. I'm trying to keep the client as simple as possible.
Ideally, I'd like to write the client code similar to something like the below pseudocode:
Reference1.Service1Client MyService = new Reference1.Service1Client("Service1");
DelayedDataSet<MyRecordType> MyResultSet = MyService.GetAllCustomers();
MyResultSet.First();
while (!MyResultSet.Eof)
{
Console.Writeline(MyResultSet.CurrentRecord().CUSTFNAME + " " + MyResultSet.CurrentRecord().CUSTLNAME);
Console.Writeline("Press Enter to see the next customer");
Console.Readline();
MyResultSet.Next();
}
Of course, DelayedDataSet is something I just made up, and I'm hoping something like it exists in .NET.
The call to MyService.GetAllCustomers() would return this DelayedDataSet object, with would not actually contain the actual records. The actual data wouldn't come over the wire until CurrentRecord() is called. Next() and Previous() would simply update a cursor on the server side to point to the appropriate record. I don't want the client to have any direct visibility to the database or Entity Framework.
I'm guessing that the way I wrote the code probably won't work over WCF, and that the functions like CurrentRecord(), Next(), First(), etc. would have to be separate service contract operations. I guess I'm just looking for a way to do this without having to write all my own code to cache the results on the server, somehow persist the data sets server side, write all the retrieval and navigation code in my service library, etc. I'm hoping most of this is already done for me.
It seems like this would be a very commonly needed function. So, does something like this exist?
-Joe
No, that's not what WCF is designed to do.
In WCF, the very basic core architecture is that you have a client and a server, and nothing but (XML-)serialized data going between the two over the wire.
WCF is not a remote-procedure call method, or some sort of remote object mechanism - there is no connection between the client and the server except the serialized message that conforms to the service (and data) contracts defined between the two.
WCF is not designed to handle huge data volumes - it's designed to handle individual messages (GetCustomerByID(42) and such). Since WCF is from the ground up designed to be interoperable with other platforms (non - .NET, too - like Java, Ruby etc.) you should definitely not be using heavy-weight .NET specific types like DataSet anyway - use proper objects.
Also, since WCF ultimately serializes everything to XML and send it across a wire, all the data being passed must be expressible in XML schema - which excludes interfaces and/or generics.
From what I'm reading in your post, what you're looking for is more of a "in-proc" data access layer - not a service level. So if you want to keep going down this path, you should investigate the repository and unit-of-work patterns in conjunction with Entity Framework.
More info:
MSDN: What is Windows Communication Foundation?
WCF Essentials—A Developer's Primer
Picture of the very basic WCF architecture from that Primer - there's only a wire with a serialized message connecting client and server - nothing more; but serialization will always happen
Is it possible to cache a page render on an iis web server, but still receive and write query string values (that don't affect output) to the database? So that the page render does not have to wait for the database trip to execute in order to serve the page? If possible, how do I implement?
For example, we track various affiliate and search marketing data via query strings, and in the master page code behind, we write the given query string data to the database. The output of the page doesn't change at all for the user (however we may set a cookie based off the qs parameter).
My understanding is that the page render has to wait for the database trip to fully execute in order to render the page. Is that even true?
Yes in general though it can depend on how one handles the caching.
First, you should move that tracking stuff to where it belongs -- a HttpModule. Page need not concern itself. Second, what you probably want to look into is some sort of fire and forget service call or message queueing. This makes the database write a non-blocking operation rather than a blocking operation.
Some options for making the operation non-blocking:
if you are actually writing to a web service, there is an underappreciated [OperationContract(IsOneWay = true)] decoration. Tells the generated proxy to fire and forget the call, will not wait for a response.
Another option would be to use the Asynchronous ADO.NET bits, especially BeginExecuteNonQuery. If you don't handle the callback this should just execute off your thread.
You could always just spawn a thread and deal with it in a non-blocking manner yourself. Just be real careful about handling errors on this thread -- unhandled exceptions will take out the app domain.
I have been given a task where it should be possible for a user to pass some information to a database table.
The table should be seen as a queue.
My question is:
Is it possible to execute some code on the webserver asynchronously, so the users can use the website for others tasks meanwhile processing the queue?
Is it possible to use the Thread class and how ?
Look into Asynchronous Pages as a start - it is teh easiest way to do what you describe.
http://msdn.microsoft.com/en-us/magazine/cc163725.aspx
You could use a service bus to get this done. If you feel up to it you could have a look at my open source esb:
http://shuttle.codeplex.com
It has an implementation that can use a sql table as a queue.
I have a web service that executes a task that may take hours to finish (asynchronously)
I would like to share the status of that task by all the clients that connects to the server (I'm using a web application for this)
For example, the first client that calls the page http://localhost/process.aspx
will instantiate the web service and it will call a method to start executing the task. A percentage number will be displayed showing the status of completion. I can do this by polling the web service using AJAX.
If there is another client that tries to opens that page, it should get the same percentage information so no new instances of the web service are created.
How is the best way of doing this?
I thought about different solutions but sooner or later I find new problems.
These are some of the possible alternatives:
Create an static object of the Web service.
Create the object in the global.asax file.
Do you guys have any other ideas? I'm not too familiar designing web sites and this is driving me crazy. I would appreciate if you guys could provide some code snippets.
Thanks
The issue is ensuring that the information pertaining to the single instance of a process is stored in exactly one place.
Your initial thinking can be applied, for instance, by using the Application object, but that will break down in a clustered IIS scenario.
I am not posative that a database is the absolute best solution, but I believe it would give you what you want.
If 100 clients try to start the process at the same time, only one can succeed, right? The databases locking facility will help you make that happen.
There's a method (I'm assuming WCF for the web service) that allows you to have exactly one instance of the service run... link
I think this is what you are trying to accomplish.
Assuming I have understood your requirements correctly. Your webservice should not be creating the instance of the “worker” object.
Your webservice request should log to either a database (as the other poster noted) or a messagequeue of somesort. At this point your “worker” processer (probably some type of service) should take over the job as it requires.
Basically you want to break up your application into something like this
| Webservice | ---------- | Datastore |-----------| Worker |
Any further requests regarding the batch should be managed by the webservice querying the datastore.
Remember webservices are NOT DESIGNED TO DO WORK.