T
Tom Purvis
I'm writing a J2EE app that uses CMP to manage all entity beans'
persistance. I'd like to use a pessimistic concurrency approach,
where a user will be blocked from opening an entity (record) if
some other user already has it open. When my code asks the container
to open an entity that another client thread has open, I'd like to
have the container throw an exception.
I'm using a Stateless Session bean to operate on the Entity Bean.
A Servlet instantiates the Session bean, then provides the ID of
the record it wants to open. The session bean calls findByPrimaryKey
using the ID.
Once I've used the bean to populate a Form on the client's returned
page, I put a reference to the bean's Local Interface into the
HttpSession obj. This keeps a reference to it in the client thread,
but the container may passivate it. I had hoped that keeping this
reference would effectively lock the row so that other attempts to
pull up the entity would fail. If the session times out, the bean
would be closed and freed.
So I opened a record for editing, then logged a second user on and
had that user attempt to open the same record. Both users could open
the same record, and stomp on each others' changes.
I'm new enough to EJBs that I wasn't sure if it should be working this
way. Then I found a key in standardjbosscmp-jdbc.xml and standardjaws.xml
called <row-locking>. I set it from False to True and bounced JBoss.
I hoped that would change make my approach work, but no dice. I still
have very optimistic concurrency.
I am using JBoss to develop, and will most certainly move the app
to production on JBoss. My development environment is JBoss 3.2.1
with MySQL 4.0.13 as the Data Store. When I go to production,
the datastore will probably be MS SQL Server (horrors!). Not my
favorite DBMS, but it is more likely to support advanced features
like row-level locking. MySQL is supposed to support RLL as of
version 4.0x, but I'm wondering if it isn't just a problem with
my choice of datasource.
So the questions:
1. Am I even on the right track expecting this to work? Is there a
better J2EE approach to avoiding this concurrency problem? I can code
a locking scheme, but naturally I'd rather have the container do my
locking for me if it's at all possible.
2. Is it possible that this is failing because I'm using MySQL as
my datasource? I'm using version 4.0.13 of MySQL with InnoDB, and
I'm using InnoDB AFAIK. In other words, if everything else was right,
would this approach work?
TIA for any advice or info.
persistance. I'd like to use a pessimistic concurrency approach,
where a user will be blocked from opening an entity (record) if
some other user already has it open. When my code asks the container
to open an entity that another client thread has open, I'd like to
have the container throw an exception.
I'm using a Stateless Session bean to operate on the Entity Bean.
A Servlet instantiates the Session bean, then provides the ID of
the record it wants to open. The session bean calls findByPrimaryKey
using the ID.
Once I've used the bean to populate a Form on the client's returned
page, I put a reference to the bean's Local Interface into the
HttpSession obj. This keeps a reference to it in the client thread,
but the container may passivate it. I had hoped that keeping this
reference would effectively lock the row so that other attempts to
pull up the entity would fail. If the session times out, the bean
would be closed and freed.
So I opened a record for editing, then logged a second user on and
had that user attempt to open the same record. Both users could open
the same record, and stomp on each others' changes.
I'm new enough to EJBs that I wasn't sure if it should be working this
way. Then I found a key in standardjbosscmp-jdbc.xml and standardjaws.xml
called <row-locking>. I set it from False to True and bounced JBoss.
I hoped that would change make my approach work, but no dice. I still
have very optimistic concurrency.
I am using JBoss to develop, and will most certainly move the app
to production on JBoss. My development environment is JBoss 3.2.1
with MySQL 4.0.13 as the Data Store. When I go to production,
the datastore will probably be MS SQL Server (horrors!). Not my
favorite DBMS, but it is more likely to support advanced features
like row-level locking. MySQL is supposed to support RLL as of
version 4.0x, but I'm wondering if it isn't just a problem with
my choice of datasource.
So the questions:
1. Am I even on the right track expecting this to work? Is there a
better J2EE approach to avoiding this concurrency problem? I can code
a locking scheme, but naturally I'd rather have the container do my
locking for me if it's at all possible.
2. Is it possible that this is failing because I'm using MySQL as
my datasource? I'm using version 4.0.13 of MySQL with InnoDB, and
I'm using InnoDB AFAIK. In other words, if everything else was right,
would this approach work?
TIA for any advice or info.