You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@geronimo.apache.org by Matt Hogstrom <ma...@hogstrom.org> on 2006/07/27 04:47:37 UTC
Pessimistic locking strategy for CMP beans in 1.1.1
I wanted to let people know about one of the fixes I'm putting into 1.1.1. I addressed this issue
in a note previously and it has to do with our locking model for CMP persistence. This note is
applicable to OpenEJB-2.1.1-SNAPSHOT as well as TranQL 1.3.1-SNAPSHOT.
Currently users deploying CMP beans have no mechanism to specify if they want to lock the row in a
DB when they execute a finder on a CMP entity. This means that there is no locking in the database
and multiple concurrent users have a high degree of either corrupting data or getting SQL -911
deadlocks in their application.
To mitigate this issue I am adding a few new elements to the OpenEJB schema to allow users to
specify this option. Here is my current thinking and I'd like some feedback if you have time and
are interested.
Basically there are two ways locking is implemented. The first is a pessimistic strategy that
relies on the database to enforce locking. Unfortunately, different DBMS's have various ways to
address this. It is generally accomplished by setting the appropriate isolation level and
specifying *for update* on the select clause. I believe that with the knowledge of a pessimistic
strategy the DBSyntaxGenerators in TranQL can put out the appropriate SQL to accomplish this.
The second method is to use an optimistic strategy where a mono incrementing column or timestamp is
used to disambiguate tuples from each other. The container keeps track of the value of the
optimistic column. I'm planning on implementing this later but thought we'd make the schema changes
now.
I would like to add a <locking-strategy> section to the entity-bean element after the pre-fetch group.
The locking strategy really is either optimistic or pessimistic. Currently I'm focusing on
pessimistic and need to finalize the optimistic options but this is enough for discussion.
Something like:
<xs:element name="locking-strategy">
<xs:complexType>
<xs:sequence>
<xs:element name="optimistic-locking" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="optimistic-column" type="xs:string"/>
<xs:element name="optimistic-type" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType>
<xs:sequence>
<xs:element name="pessimistic-locking" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="select-for-update" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
This seems clunky to me...is there a better way to express this idea as the locking strategy
requires one or the other but not both. I think the above is ok and will validate in the builder
but want some feedback.
Here is what I would expect a user to code:
<entity>
<ejb-name>KeyGenEJB</ejb-name>
<table-name>KeyGenEJB</table-name>
<cmp-field-mapping>
<cmp-field-name>keyVal</cmp-field-name>
<table-column>keyVal</table-column>
</cmp-field-mapping>
<cmp-field-mapping>
<cmp-field-name>keyName</cmp-field-name>
<table-column>keyName</table-column>
</cmp-field-mapping>
<locking-strategy>
<pessimistic-locking>
</locking-strategy>
.
.
or
.
.
<locking-strategy>
<optimistic-locking>
<optimistic-column>occColumn</optimistic-column>
<optimistic-type>TIMESTAMP</optimistic-type>
</locking-strategy>
</entity>
BAH...NOTE I wrote this abot 8 hours ago and here it sits unsent...bummer. Well, here it is now.
Re: Pessimistic locking strategy for CMP beans in 1.1.1
Posted by Matt Hogstrom <ma...@hogstrom.org>.
Thanks Mohammed...that's what I ws looking for. cheers.
Mohammed Nour wrote:
> Hi Matt...
>
> On 7/27/06, Matt Hogstrom <ma...@hogstrom.org> wrote:
>>
>> I wanted to let people know about one of the fixes I'm putting into
>> 1.1.1. I
>> addressed this issue
>> in a note previously and it has to do with our locking model for CMP
>> persistence. This note is
>> applicable to OpenEJB-2.1.1-SNAPSHOT as well as TranQL 1.3.1-SNAPSHOT.
>>
>> Currently users deploying CMP beans have no mechanism to specify if they
>> want to lock the row in a
>> DB when they execute a finder on a CMP entity. This means that there is
>> no locking in the database
>> and multiple concurrent users have a high degree of either corrupting
>> data
>> or getting SQL -911
>> deadlocks in their application.
>>
>> To mitigate this issue I am adding a few new elements to the OpenEJB
>> schema to allow users to
>> specify this option. Here is my current thinking and I'd like some
>> feedback if you have time and
>> are interested.
>>
>> Basically there are two ways locking is implemented. The first is a
>> pessimistic strategy that
>> relies on the database to enforce locking. Unfortunately, different
>> DBMS's have various ways to
>> address this. It is generally accomplished by setting the appropriate
>> isolation level and
>> specifying *for update* on the select clause. I believe that with the
>> knowledge of a pessimistic
>> strategy the DBSyntaxGenerators in TranQL can put out the appropriate SQL
>> to accomplish this.
>>
>> The second method is to use an optimistic strategy where a mono
>> incrementing column or timestamp is
>> used to disambiguate tuples from each other. The container keeps
>> track of
>> the value of the
>> optimistic column. I'm planning on implementing this later but thought
>> we'd make the schema changes
>> now.
>>
>> I would like to add a <locking-strategy> section to the entity-bean
>> element after the pre-fetch group.
>>
>> The locking strategy really is either optimistic or
>> pessimistic. Currently I'm focusing on
>> pessimistic and need to finalize the optimistic options but this is
>> enough
>> for discussion.
>>
>> Something like:
>>
>> <xs:element name="locking-strategy">
>> <xs:complexType>
>> <xs:sequence>
>> <xs:element name="optimistic-locking"
>> maxOccurs="1">
>> <xs:complexType>
>> <xs:sequence>
>> <xs:element name="optimistic-column"
>> type="xs:string"/>
>> <xs:element name="optimistic-type"
>> type="xs:string"/>
>> </xs:sequence>
>> </xs:complexType>
>> </xs:element>
>> </xs:sequence>
>> </xs:complexType>
>> <xs:complexType>
>> <xs:sequence>
>> <xs:element name="pessimistic-locking"
>> maxOccurs="1">
>> <xs:complexType>
>> <xs:sequence>
>> <xs:element name="select-for-update"
>> minOccurs="0"/>
>> </xs:sequence>
>> </xs:complexType>
>> </xs:element>
>> </xs:sequence>
>> </xs:complexType>
>> </xs:element>
>>
>> This seems clunky to me...is there a better way to express this idea as
>> the locking strategy
>> requires one or the other but not both. I think the above is ok and will
>> validate in the builder
>> but want some feedback.
>
>
> To make an instance of this XML-Schema contains only one locking strategy,
> you have to make it as follows:
>
> <xs:element name="locking-strategy">
> <xs:complexType>
> <xs:sequence>
> <xs:choice>
> <xs:element name="optimistic-locking"
> maxOccurs="1">
> <xs:complexType>
> <xs:sequence>
> <xs:element name="optimistic-column"
> type="xs:string"/>
> <xs:element name="optimistic-type"
> type="xs:string"/>
> </xs:sequence>
> </xs:complexType>
> </xs:element>
> <xs:element name="pessimistic-locking"
> maxOccurs="1">
> <xs:complexType>
> <xs:sequence>
> <xs:element name="select-for-update"
> minOccurs="0"/>
> </xs:sequence>
> </xs:complexType>
> </xs:element>
> </xs:choice>
> </xs:sequence>
> <xs:complexType>
> </xs:element>
>
>
> Here is what I would expect a user to code:
>>
>> <entity>
>> <ejb-name>KeyGenEJB</ejb-name>
>> <table-name>KeyGenEJB</table-name>
>> <cmp-field-mapping>
>> <cmp-field-name>keyVal</cmp-field-name>
>> <table-column>keyVal</table-column>
>> </cmp-field-mapping>
>> <cmp-field-mapping>
>> <cmp-field-name>keyName</cmp-field-name>
>> <table-column>keyName</table-column>
>> </cmp-field-mapping>
>> <locking-strategy>
>> <pessimistic-locking>
>> </locking-strategy>
>> .
>> .
>> or
>> .
>> .
>> <locking-strategy>
>> <optimistic-locking>
>> <optimistic-column>occColumn</optimistic-column>
>> <optimistic-type>TIMESTAMP</optimistic-type>
>> </locking-strategy>
>> </entity>
>>
>> BAH...NOTE I wrote this abot 8 hours ago and here it sits
>> unsent...bummer. Well, here it is now.
>>
>
Re: Pessimistic locking strategy for CMP beans in 1.1.1
Posted by Mohammed Nour <no...@gmail.com>.
Hi Matt...
On 7/27/06, Matt Hogstrom <ma...@hogstrom.org> wrote:
>
> I wanted to let people know about one of the fixes I'm putting into 1.1.1. I
> addressed this issue
> in a note previously and it has to do with our locking model for CMP
> persistence. This note is
> applicable to OpenEJB-2.1.1-SNAPSHOT as well as TranQL 1.3.1-SNAPSHOT.
>
> Currently users deploying CMP beans have no mechanism to specify if they
> want to lock the row in a
> DB when they execute a finder on a CMP entity. This means that there is
> no locking in the database
> and multiple concurrent users have a high degree of either corrupting data
> or getting SQL -911
> deadlocks in their application.
>
> To mitigate this issue I am adding a few new elements to the OpenEJB
> schema to allow users to
> specify this option. Here is my current thinking and I'd like some
> feedback if you have time and
> are interested.
>
> Basically there are two ways locking is implemented. The first is a
> pessimistic strategy that
> relies on the database to enforce locking. Unfortunately, different
> DBMS's have various ways to
> address this. It is generally accomplished by setting the appropriate
> isolation level and
> specifying *for update* on the select clause. I believe that with the
> knowledge of a pessimistic
> strategy the DBSyntaxGenerators in TranQL can put out the appropriate SQL
> to accomplish this.
>
> The second method is to use an optimistic strategy where a mono
> incrementing column or timestamp is
> used to disambiguate tuples from each other. The container keeps track of
> the value of the
> optimistic column. I'm planning on implementing this later but thought
> we'd make the schema changes
> now.
>
> I would like to add a <locking-strategy> section to the entity-bean
> element after the pre-fetch group.
>
> The locking strategy really is either optimistic or
> pessimistic. Currently I'm focusing on
> pessimistic and need to finalize the optimistic options but this is enough
> for discussion.
>
> Something like:
>
> <xs:element name="locking-strategy">
> <xs:complexType>
> <xs:sequence>
> <xs:element name="optimistic-locking"
> maxOccurs="1">
> <xs:complexType>
> <xs:sequence>
> <xs:element name="optimistic-column"
> type="xs:string"/>
> <xs:element name="optimistic-type"
> type="xs:string"/>
> </xs:sequence>
> </xs:complexType>
> </xs:element>
> </xs:sequence>
> </xs:complexType>
> <xs:complexType>
> <xs:sequence>
> <xs:element name="pessimistic-locking"
> maxOccurs="1">
> <xs:complexType>
> <xs:sequence>
> <xs:element name="select-for-update"
> minOccurs="0"/>
> </xs:sequence>
> </xs:complexType>
> </xs:element>
> </xs:sequence>
> </xs:complexType>
> </xs:element>
>
> This seems clunky to me...is there a better way to express this idea as
> the locking strategy
> requires one or the other but not both. I think the above is ok and will
> validate in the builder
> but want some feedback.
To make an instance of this XML-Schema contains only one locking strategy,
you have to make it as follows:
<xs:element name="locking-strategy">
<xs:complexType>
<xs:sequence>
<xs:choice>
<xs:element name="optimistic-locking"
maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="optimistic-column"
type="xs:string"/>
<xs:element name="optimistic-type"
type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="pessimistic-locking"
maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="select-for-update"
minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:sequence>
<xs:complexType>
</xs:element>
Here is what I would expect a user to code:
>
> <entity>
> <ejb-name>KeyGenEJB</ejb-name>
> <table-name>KeyGenEJB</table-name>
> <cmp-field-mapping>
> <cmp-field-name>keyVal</cmp-field-name>
> <table-column>keyVal</table-column>
> </cmp-field-mapping>
> <cmp-field-mapping>
> <cmp-field-name>keyName</cmp-field-name>
> <table-column>keyName</table-column>
> </cmp-field-mapping>
> <locking-strategy>
> <pessimistic-locking>
> </locking-strategy>
> .
> .
> or
> .
> .
> <locking-strategy>
> <optimistic-locking>
> <optimistic-column>occColumn</optimistic-column>
> <optimistic-type>TIMESTAMP</optimistic-type>
> </locking-strategy>
> </entity>
>
> BAH...NOTE I wrote this abot 8 hours ago and here it sits
> unsent...bummer. Well, here it is now.
>
Re: Pessimistic locking strategy for CMP beans in 1.1.1
Posted by Oliver Zeigermann <ol...@gmail.com>.
Hey, again!
Thanks for the detailed answers. See my comments inline.
2006/7/27, Matt Hogstrom <ma...@hogstrom.org>:
> > 2.) Are the requests to load the bean from the db still inside a
> > transaction?
>
> Yes
>
> If so what isolation level?
>
> Ahhh....the 64,000 dollar question. Every RDBMs is slightly different in their implementations.
> Oracle would use read-committed as would DB2 for the optimistic scenario. For pessimistic DB2 would
> need to bump up to Read Stability (RS) which is the equivalent of REPEATABLE_READ. This is because
> the lock duration is different for DB2 than it is for Oracle at READ_COMMITTED. So the correct
> answer is it depends.
So, if I understand this correctly than this is something the user has
to set, right? If so don't you need another field in the bean
descriptor for the isolation level of the request?
Additionally, I have no big idea of DB2 isoaltion levels, but I had
the impression SERIALIZABLE was the one for an optimistic scenario in
Oracle - even though it does not sound like it would be. AFAIK this
level does not use any blocking locks, but rahter some sort of
snapshot isolation. Am I wrong?
> > 3.) Is there something like caching of beans in Geronimo? If so how is
> > this handled, especially in a distributed scenario?
>
> Currently there is a per Tx cache. I believe Gianny was working on a global cache but I don't know
> the state of it. Although, the global cache is on a per G instance and not a cluster. We need to
> work on that.
Very interesting! Have you already inverstigated what happens when
some objects in a tx come from the cache and others from the db? Also,
what to do when an object changes in the db while it is used from the
cache. Might happen when one cluster node writes changes to an object
in the db. Is there any notification mechanism? I guess JGroups is no
option because of the bad LGPL license. Are there any alternatives?
Any thoughts to enlighten me?
Cheers
Oliver
Re: Pessimistic locking strategy for CMP beans in 1.1.1
Posted by Matt Hogstrom <ma...@hogstrom.org>.
Oliver Zeigermann wrote:
> Hi, Matt!
>
> I am rather new to Geronimo, so please be patient if my questions
> sound rather stupid.
>
> 2006/7/27, Matt Hogstrom <ma...@hogstrom.org>:
>> The second method is to use an optimistic strategy where a mono
>> incrementing column or timestamp is
>> used to disambiguate tuples from each other. The container keeps
>> track of the value of the
>> optimistic column. I'm planning on implementing this later but
>> thought we'd make the schema changes
>> now.
>
> Questions:
> 1.) I was wondering what to do upon conflict. I can only think of
> letting the transaction fail. Right?
For optimistic there are two options I think. One is to simply rollback the Tx and call it a day
which is probably the most common scenario. The other would be to Roll the Tx back and then restart
the request. The assumption being that since this is an optimistic scenario the second attempt
would most probably succeed.
> 2.) Are the requests to load the bean from the db still inside a
> transaction?
Yes
If so what isolation level?
Ahhh....the 64,000 dollar question. Every RDBMs is slightly different in their implementations.
Oracle would use read-committed as would DB2 for the optimistic scenario. For pessimistic DB2 would
need to bump up to Read Stability (RS) which is the equivalent of REPEATABLE_READ. This is because
the lock duration is different for DB2 than it is for Oracle at READ_COMMITTED. So the correct
answer is it depends.
I guess there still can be a deadlock in the db.
I don't think you can 100% avoid those but a lot of that also depends on the applciation to enlist
resources in the same order to avoid that.
> 3.) Is there something like caching of beans in Geronimo? If so how is
> this handled, especially in a distributed scenario?
Currently there is a per Tx cache. I believe Gianny was working on a global cache but I don't know
the state of it. Although, the global cache is on a per G instance and not a cluster. We need to
work on that.
>
> Thanks in advance for any hints and cheers
>
> Oliver
>
>
>
Re: Pessimistic locking strategy for CMP beans in 1.1.1
Posted by Oliver Zeigermann <ol...@gmail.com>.
Hi, Matt!
I am rather new to Geronimo, so please be patient if my questions
sound rather stupid.
2006/7/27, Matt Hogstrom <ma...@hogstrom.org>:
> The second method is to use an optimistic strategy where a mono incrementing column or timestamp is
> used to disambiguate tuples from each other. The container keeps track of the value of the
> optimistic column. I'm planning on implementing this later but thought we'd make the schema changes
> now.
Questions:
1.) I was wondering what to do upon conflict. I can only think of
letting the transaction fail. Right?
2.) Are the requests to load the bean from the db still inside a
transaction? If so what isolation level? I guess there still can be a
deadlock in the db.
3.) Is there something like caching of beans in Geronimo? If so how is
this handled, especially in a distributed scenario?
Thanks in advance for any hints and cheers
Oliver
Re: Pessimistic locking strategy for CMP beans in 1.1.1
Posted by Dain Sundstrom <da...@iq80.com>.
I'm not sure this will cover the common strategies used by most
containers. I recall implementing a few different strategies in
another appserver:
o DB auto update sequence
o Container manual update sequence
o DB last modified timestamp column
o Container manual update sequence (unreliable but people use it)
o Check column values haven't changed between select an update
o All columns
o Some special columns
o Only columns being updated
o All columns that were read in during the tx
I doubt we need all of these, but I think we should allow room for
growth in the schema.
-dain
On Jul 31, 2006, at 7:38 AM, Matt Hogstrom wrote:
> Perhaps one additional element in the optimistic section like:
>
> <concurrency-control>[DATABASE | CONTAINER]</concurrency-control>
>
>
>
> Dain Sundstrom wrote:
>> +1 looks good
>> On Jul 26, 2006, at 7:47 PM, Matt Hogstrom wrote:
>>> <locking-strategy>
>>> <optimistic-locking>
>>> <optimistic-column>occColumn</optimistic-column>
>>> <optimistic-type>TIMESTAMP</optimistic-type>
>>> </locking-strategy>
>> one comment... this xml implies that the database is handling the
>> auto increment/update of the optimistic lock column. I have seen
>> schemas that assume that the application code will be handling
>> this, with some sql like this:
>> UPDATE foo
>> SET value = newValue, ver = 5
>> WHERE pk = myPk AND ver = 4
>> If the database is auto updating the row, you will need to reread
>> the column after any update, so if you make another update in the
>> same transaction, you can assure you know the current value of the
>> optimistic column.
>> -dain
Re: Pessimistic locking strategy for CMP beans in 1.1.1
Posted by Matt Hogstrom <ma...@hogstrom.org>.
Perhaps one additional element in the optimistic section like:
<concurrency-control>[DATABASE | CONTAINER]</concurrency-control>
Dain Sundstrom wrote:
> +1 looks good
>
> On Jul 26, 2006, at 7:47 PM, Matt Hogstrom wrote:
>
>> <locking-strategy>
>> <optimistic-locking>
>> <optimistic-column>occColumn</optimistic-column>
>> <optimistic-type>TIMESTAMP</optimistic-type>
>> </locking-strategy>
>
> one comment... this xml implies that the database is handling the auto
> increment/update of the optimistic lock column. I have seen schemas
> that assume that the application code will be handling this, with some
> sql like this:
>
> UPDATE foo
> SET value = newValue, ver = 5
> WHERE pk = myPk AND ver = 4
>
> If the database is auto updating the row, you will need to reread the
> column after any update, so if you make another update in the same
> transaction, you can assure you know the current value of the optimistic
> column.
>
> -dain
>
>
>
Re: Pessimistic locking strategy for CMP beans in 1.1.1
Posted by Dain Sundstrom <da...@iq80.com>.
+1 looks good
On Jul 26, 2006, at 7:47 PM, Matt Hogstrom wrote:
> <locking-strategy>
> <optimistic-locking>
> <optimistic-column>occColumn</optimistic-column>
> <optimistic-type>TIMESTAMP</optimistic-type>
> </locking-strategy>
one comment... this xml implies that the database is handling the
auto increment/update of the optimistic lock column. I have seen
schemas that assume that the application code will be handling this,
with some sql like this:
UPDATE foo
SET value = newValue, ver = 5
WHERE pk = myPk AND ver = 4
If the database is auto updating the row, you will need to reread the
column after any update, so if you make another update in the same
transaction, you can assure you know the current value of the
optimistic column.
-dain