wood burning stoves 2.0*
The moose likes EJB and other Java EE Technologies and the fly likes Locking between instances of a beans Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Android Security Essentials Live Lessons this week in the Android forum!
JavaRanch » Java Forums » Java » EJB and other Java EE Technologies
Bookmark "Locking between instances of a beans" Watch "Locking between instances of a beans" New topic
Author

Locking between instances of a beans

Mark Herschberg
Sheriff

Joined: Dec 04, 2000
Posts: 6037
When I firts learned EJBs, I was told, "you can program in a single threaded model," that is, you can pretend there is only on thread in the system, because the application server takes care of threading issues. Well, today I learned that this advice doesn't always hold. Here's what I need to do...
This is another question about my trading application. Two actually.
Issue 1:
--------
I've got a bunch of different securities: stocks, bonds, etc... let's say a few hundred. I've got a special session bean that crosses two orders. So there's a list of orders waiting to be filled (limit orders), sitting in a DB table. When a market order comes in, it must grab the first limit order and the two will cross ("cancel each other out" so to speak--in other words, remove the limit order from the table). Specifically, the algorithm in the session bean that does this will grab the first limit order, and then cross it.
Now if I get two market orders for the same security "concurrently" I'm worried about the following. The first instance of the session bean will grab the first limit order in the table. But before it gets crossed (removed), the bean is swapped out by the JVM scheduler and the other bean instance is run. When that tried to grab the "first" limit order, it should really be getting the second limit order.
How can I do this? I think it can be done with an appropriate transaction isolation level (set it to serializable?). Is this right? If not, any other way to do this?
Issue 2:
--------Even if I do the above, there still ultimately needs to be a single pipe per security, somewhere in the system. (It has to do with our trading system not only allowing trading, but mimicing the behvaior of "the rest of the market.") Basically, I'm going to need a single instance of a session bean for each and every security. But EJBs don't support this directly! Although I can have stateful session beans, I can't call them by name. That is, when I get an order for IBM stock, I need to call a special session bean to handle IBM stock. The good news is that all the session beans behave the same way. So how can I get this behavior: having a single instance of a session bean dedicated to a particular security?
I think I can do it as follows. This session bean will have a single entry method. The first thing I do in that method is grab an entity bean. As above, this must temporily "lock" the entity bean so no one else can get it. (Hmm, maybe this is the same issue as issue 1.) When the method completes, the eneitty bean is unlocked.
This means if I have 30 instances of the session bean, I can trade 30 simultaneous securities at once--assuming all 30 trades are in different securities. Even if I have 30 beans, and get 30 trades all in the same security, they will ultimately have to be queued up one after another.
Am I understanding this right? Is this the correct way to do this, or is there a better way?
--Mark
Chris Mathews
Ranch Hand

Joined: Jul 18, 2001
Posts: 2712
Originally posted by Mark Herschberg:
When I first learned EJBs, I was told, "you can program in a single threaded model," that is, you can pretend there is only on thread in the system, because the application server takes care of threading issues.

I have found that one does not need to worry about currency in only the simplest cases, things like database-driven websites. In most applications of any complexity, concurrency is going to be an issue not matter what technology is used.
Originally posted by Mark Herschberg:
This is another question about my trading application. Two actually.
Issue 1:
--------
I've got a bunch of different securities: stocks, bonds, etc... let's say a few hundred. I've got a special session bean that crosses two orders. So there's a list of orders waiting to be filled (limit orders), sitting in a DB table. When a market order comes in, it must grab the first limit order and the two will cross ("cancel each other out" so to speak--in other words, remove the limit order from the table). Specifically, the algorithm in the session bean that does this will grab the first limit order, and then cross it.
Now if I get two market orders for the same security "concurrently" I'm worried about the following. The first instance of the session bean will grab the first limit order in the table. But before it gets crossed (removed), the bean is swapped out by the JVM scheduler and the other bean instance is run. When that tried to grab the "first" limit order, it should really be getting the second limit order.
How can I do this? I think it can be done with an appropriate transaction isolation level (set it to serializable?). Is this right? If not, any other way to do this?

The problem with isolation levels is that Application Servers usually defer these to the database. Therefore, depending on your RDBMS your functionality is going to be different. For example, Oracle goes with an optimistic approach by not checking locks until commit time. This is great for concurrency but can result in the loss of work. You may be better off just writing your own Lock Manager. I suggest taking a look at the Pessimistic Offline Lock Pattern from PEAA. It has a great discussion on these issues.
Originally posted by Mark Herschberg:
Issue 2:
--------Even if I do the above, there still ultimately needs to be a single pipe per security, somewhere in the system. (It has to do with our trading system not only allowing trading, but mimicing the behvaior of "the rest of the market.") Basically, I'm going to need a single instance of a session bean for each and every security. But EJBs don't support this directly! Although I can have stateful session beans, I can't call them by name. That is, when I get an order for IBM stock, I need to call a special session bean to handle IBM stock. The good news is that all the session beans behave the same way. So how can I get this behavior: having a single instance of a session bean dedicated to a particular security?
I think I can do it as follows. This session bean will have a single entry method. The first thing I do in that method is grab an entity bean. As above, this must temporily "lock" the entity bean so no one else can get it. (Hmm, maybe this is the same issue as issue 1.) When the method completes, the eneitty bean is unlocked.
This means if I have 30 instances of the session bean, I can trade 30 simultaneous securities at once--assuming all 30 trades are in different securities. Even if I have 30 beans, and get 30 trades all in the same security, they will ultimately have to be queued up one after another.
Am I understanding this right? Is this the correct way to do this, or is there a better way?

I don't think Session Beans are the solution you really want. I would consider going with JMS for the processing of these items. It doesn't sound, from your description, that this activity should be synchronous. JMS and MDBs will give you more control over process flow.
If the number of securities is fixed and manageable then you could assign a separate MDB for each security and control the Messages consumed with a Message Selector. Each MDB deployment could then be nailed down to only one instance in your Application Server. This way you could easily get your desired isolation without completely hosing your system's concurrency level.
[ January 30, 2003: Message edited by: Chris Mathews ]
Mark Herschberg
Sheriff

Joined: Dec 04, 2000
Posts: 6037
Thanks for the response Chris. BTW, we're using WebLogic 7.0 and Oracle 9i.
OK, I'll see if I can take a look at the book, although I'm still hoping to avoid the extra work--Kyle Brown had suggested that the DB alone is usually good enough in this type of system.
As for the second issue, well, it is a JMS driven system. The problem is the number of securities isn't determined until runtime. (Otherwise I probaby would have gone with what you suggested.)
--Mark
Chris Mathews
Ranch Hand

Joined: Jul 18, 2001
Posts: 2712
Now that I rethink your problem, it is really not a candidate for Offline Concurrency since it is not spanning multiple system transactions (correct me if I am wrong).
You should be able to get away with just delegating the concurrency control to the database. However, you will need to consider things like retrying failed transactions in this case. Therefore, JMS would still be a good solution since you can configure most Application Servers (WebLogic included) to automatically retry failed messages or to send them to a dead letter queue after a number of attempts.
[ January 30, 2003: Message edited by: Chris Mathews ]
Mark Herschberg
Sheriff

Joined: Dec 04, 2000
Posts: 6037
Originally posted by Chris Mathews:
Now that I rethink your problem, it is really not a candidate for Offline Concurrency since it is not spanning multiple system transactions (correct me if I am wrong).

Correct. Once the user places an order, the transaction begins, and ends once the order is placed or crossed. In short, the user is done with this operation.

Originally posted by Chris Mathews:
You should be able to get away with just delegating the concurrency control to the database. However, you will need to consider things like retrying failed transactions in this case. Therefore, JMS would still be a good solution since you can configure most Application Servers (WebLogic included) to automatically retry failed messages or to send them to a dead letter queue after a number of attempts.

Yes, I've been debating what to do here. The system as a whole is run off of JMS. That is the only connection form the clients to the server (e.g. for order placement) is through a JMS queue. Right now, it's a single transaction (I forget what the technical term is for how the transaciton levels are set). Basically, the order message is received, then parsed, and then the order is either placed into the table, or crossed with an existing order, and in the end, an reply is sent via a different JMS queue. That is one transaction. (I learned the hard way to set redelivery to a finite number, since any exception would cause the server to go into an "infinite loop" since the devilery failed when the transaction failed.)
In a later version of the product, I'd be tempted to scale down the transaction scope, but in the first version, where we expect only a few dozen people, I don't think this will cause scalability issues.
So, um, in light of this, are my thoughts about issue 2 correct?
--Mark
--Mark
sram bahl
Greenhorn

Joined: Nov 26, 2002
Posts: 13
As for you Q1, I think you should have a SecrutiyManager Entity Bean which would log all incoming securities. Your session bean would first talk to SecurityManager to check if a particular security has been placed, if not then register its details to the manager and proceed with the order. If already procesessed by another bean you would ignore the request.
 
Consider Paul's rocket mass heater.
 
subject: Locking between instances of a beans
 
Similar Threads
Mirroring Server Data
Complex Data Structure Manipulation on an EJB Server
Serializing processing with EJBs
Who can access a session bean?
EJB Overhead and Performance