views:

219

answers:

2

Hello all,

I'm having a pressing issue and I'm hoping you all can help me out. I will try my best to explain it as well as I can.

I am augmenting a system that uses .NET remoting to allow for database calls from a thin client to a server that executes said calls. The server itself has the data access components installed on it, so it makes the actual calls to the database, and just returns the datarows to the thin client.

I just recently added transactions to these modules. I wanted to make this thread-safe, where if client thread A started a database transaction, client thread B would not be able to access client thread A's transaction. It is not necessary to allow client thread B to have it's own transaction in the meanwhile, only necessary that I do not allow client thread B to use client thread A's transaction.

There is only 1 reference to the remoting object that both of them share, and because of the underlying architecture that I will not get into, I am not able to change this. All of the Transaction objects are stored on the server in this remoting object.

I see no good way of doing this, besides perhaps passing the client thread information along with every single transaction call, which is not feasible with my pressing timelines. :-( Perhaps if the remoting object could access the calling client thread, then I would not have to pass the thread information with every call, making this feasible.

If there was some way of associating a client thread with a remoting process thread, I think that would do the trick, but there is no documentation that I could find on such a thing.

I hope I explained this well enough. All help is greatly appreciated. Thank you in advance.

+1  A: 

I am not 100% sure if this can be done, but using the CallContext may help. In a nutshell, a CallContext is an Out-Of-Band data that can be remoted across to the server, see this blog here for an example. If you do not understand what an Out-Of-Band (oob) is, look here on wikipedia. Here's another concrete example here. That may give you the clue.

Hope this helps, Best regards, Tom.

tommieb75
Thank you for this suggestion. I was not aware of the CallContext and this could help me greatly. I'm just not aware of how I can ensure that the thread information would always be passed. It seems that I would need to make sure the thread context is set for each calling thread, which might be infeasible with my timelines. Is there some event that gets fired before the remoting call, in which I could set the callcontext for that thread? Or does the callcontext keep a reference to the thread information by default? This would be a great help to me! Thank you.
jnadro52
@jnadro52: I suppose, just prior to making a remoting call, set the call context with an identifier on the client side, then on the server side, in the function that is client's remote call, read the callcontext first and build a collection, in that way you would know which client is using the thread. The only thing is the collection would have to be thread safe....
tommieb75
+1  A: 

What you're trying to do sounds kinda weird so let me see if I understand:

  • You're using a singleton on the server side this is why each client has only 1 thread on the server.

  • Assuming that the transaction process takes a long time (seconds to minutes) the other clients MUST wait until the first client has finished.

I think but I'm not sure that each client's call is creating it's own thread. If this is true then simply implementing some "lock" calls when the remote object needs to make thread safe calls should do the trick. Locking is expensive and if the transaction is taking seconds then the other guy waiting might timeout (eeK!)

This is the kind of stuff that the TransactionScope object was built for (See MSDN). I can't really assist anymore without knowing more about the arch of the solution.

Sorry... I don't know if this is useful or not.

kurtnelle
Yes this is a singleton, I should have mentioned that previously. I had a thread locking mechanism in place using the Monitor. I implemented this on the server side. This is causing issues because the thread ID keeps changing on the server side, even when the same client thread is calling the remoting object. This is the crux of the issue... how do I lock the server side process, and ensure that another client thread does not access the transaction object of the thread that created the transaction object? If I had some way of passing the thread information, then that would be possible.
jnadro52
@jnadro52: I like the call context method proposed by tommieb75 as a means to determine if it's the same caller (kinda like a session state), and use a thread safe collection from the framework. I guess that means that you may have to pass a connection object around and use it in each database call to ensure that the call is done in the transaction.
kurtnelle