Philip,
>  do the optimistic lock checks for read locks after the INSERT, DELETE,
> and UPDATES for the transaction.
  This is currently possible with setting VersionCheckOnReadLock property on
LockManager.
I think this will ensure that all three Flags become part of commit set and
thus the transactional consistent extends to consistency of the entire
dataset that the test case is demanding.

Pinaki
 

Philip Aston wrote:
> 
> Hi David,
> 
> EL does an update for each read lock at commit time, setting its version
> column to the same value. See my other post - I agree that SELECT FOR
> UPDATE is not appropriate for read locks, and I instead suggest a third
> approach; that is to do the optimistic lock checks for read locks after
> the INSERT, DELETE, and UPDATES for the transaction.
> 
> - Phil
> 
> 
> 
> dezzio wrote:
>> 
>> Hi Philip,
>> 
>> But why does EclipseLink pass the test?
>> 
>> Clearly the implementation could use SELECT FOR UPDATE when it checks 
>> the READ lock's state prior to commit.  If it did that, then both 
>> transactions would not succeed, and in fact, due to the likelihood of 
>> deadlock in our example case, they both might fail.
>> 
>> These kind of issues do not get sorted by argument.  They are settled by 
>> test cases in the TCK.  For this issue, there is no TCK test case, and 
>> thus, ipso facto, OpenJPA complies with the spec.  You can still argue 
>> that it doesn't comply with the spec in the best way, and you may be 
>> right.  I could be persuaded by understanding the behavior of competing 
>> implementations.
>> 
>> Cheers,
>> 
>> David
>> 
>> Philip Aston wrote:
>>> Hi David,
>>> 
>>> Thanks for confirming this. So to summarise where we are, we have:
>>> 
>>>  1. A reasonable use case that can fail with some unlucky timing.
>>> 
>>>  2. A technical test case demonstrating the problem that does not rely
>>> on unlucky timing.
>>> 
>>>  3. A disagreement in our readings of whether 1 and 2 are spec.
>>> compliant. Personally, I don't share your reading of the spec. In my
>>> reading, read locks are safe and provide a concrete guarantee that if
>>> locked entity is changed by another transaction, the locking transaction
>>> will not complete.
>>> 
>>> (This is a different QoS compared to a write lock - if a write lock is
>>> obtained and the pc flushed, the transaction knows that it will not fail
>>> due to another transaction updating the locked entity. Read locks are
>>> "more optimistic" and can support higher concurrency if there is minimal
>>> contention - many transactions can hold read locks, only one can hold
>>> right locks.).
>>> 
>>> 
>>> How can I convince you to change your interpretation of the spec? Anyone
>>> else have an opinion?
>>> 
>>> FWIW, EclipseLink passes the test case.
>>> 
>>> - Phil
>>> 
>>> dezzio (via Nabble) wrote:
>>>> Hi Philip,
>>>>
>>>> Let's take a closer look.
>>>>
>>>> We have two bank accounts, Account[1] and Account[2], shared
>>>> jointly by customers Innocent[1] and Innocent[2]. The bank's
>>>> business rule is that no withdrawal can be made the draws
>>>> the combined total of the accounts below zero. This rule is
>>>> enforced in the server side Java application that customer's
>>>> use.
>>>>
>>>> At the start of the banking day, the accounts stand at:
>>>>
>>>>      Account[1] balance 100.
>>>>      Account[2] balance 50.
>>>>
>>>> Innocent[1] wants to draw out all the money, and asks the
>>>> application to take 150 from Account[1]. Innocent[2] also
>>>> wants to draw out all the money, and asks the application to
>>>> take 150 from Account[2]. By itself, either transaction
>>>> would conform to the bank's business rule.
>>>>
>>>> The application implements the withdrawal logic by doing the
>>>> following for each transaction.
>>>>
>>>> For Innocent[1], read Account[1] and Account[2]. Obtain a
>>>> read lock on Account[2]. Refresh Account[2]. Deduct 150 from
>>>> Account[1]. Verify business rule, result, sum of balances =
>>>> 0. Call JPA commit.
>>>>
>>>> For Innocent[2], read Account[1] and Account[2]. Obtain a
>>>> read lock on Account[1]. Refresh Account[1]. Deduct 150 from
>>>> Account[2]. Verify business rule, result, sum of balances =
>>>> 0. Call JPA commit.
>>>>
>>>> Within JPA commit, as seen over the JDBC connections, the
>>>> following time sequence occurs. (Other time sequences can
>>>> yield the same result.)
>>>>
>>>> Innocent[1]: Check version of Account[2]: passes.
>>>>
>>>> Innocent[2]: Check version of Account[1]: passes.
>>>> Innocent[2]: Update balance of Account[2], withdraw 150,
>>>>                  setting balance to -100: does not block.
>>>> Innocent[2]: commit: successful
>>>> Innocent[2]: Receives 150.
>>>>
>>>> Innocent[1]: Update balance of Account[1], withdraw 150,
>>>>                  setting balance to -50: does not block.
>>>> Innocent[1]: commit: successful.
>>>> Innocent[1]: Receives 150.
>>>>
>>>> After the two transactions:
>>>>
>>>> Account[1]: balance -50
>>>> Account[2]: balance -100
>>>>
>>>> Clearly the bank would not be happy. What's a developer to
>>>> do?
>>>>
>>>> I think the developer needs an education about what is meant
>>>> by the JPA spec. What JPA is guaranteeing is that when JPA
>>>> commit is called, the objects with read locks will have
>>>> their versions checked. The objects with write locks will
>>>> have their versions checked and changed. The objects that
>>>> have been modified will have their versions checked, their
>>>> information updated, and their versions changed. Clearly all
>>>> of these rules were enforced in the above example.
>>>>
>>>> If the developer had used write locks, both transactions
>>>> would not have succeeded. In fact, for the above example and
>>>> a similar time sequence, if write locks had been used in
>>>> place of read locks, there would have been deadlock.
>>>>
>>>> Now, if in fact, I'm wrong about my interpretation of the
>>>> JPA spec (and it wouldn't be the first time) then you have a
>>>> case. I'd be curious to know whether other JPA
>>>> implementations pass your elegant test case, and what they
>>>> are doing differently that makes it so.
>>>>
>>>> Also, if I am wrong about my interpretation, then the JPA
>>>> TCK needs a test case that will snag this failure, because
>>>> OpenJPA passes the current JPA TCK.
>>>>
>>>> Cheers,
>>>>
>>>> David
>>>>
>>>> Philip Aston wrote:
>>>>
>>>>> Oh yeah - my bad. Try this one instead:
>>>>>
>>>>> Suppose there are a set of Accounts, and a business rule that says
>>>>> that the net balance must be positive.
>>>>>
>>>>> Innocent wants to draw down on Account 1 as far as possible. It read
>>>>> locks the of Accounts, sums up the value, and and subtracts the
>>>>> positive total from Account 1. Innocent begins its commit, and its
>>>>> read locks are validated.
>>>>>
>>>>> Meanwhile InnocentToo does the same for Account 2, and commits.
>>>>>
>>>>> Innocent updates Account 1 and finishes its commit.
>>>>>
>>>>> The total in account summary is now negative, violating the business
>>>>> rule. If read locks worked as I think they should, Innocent would have
>>>>> received an OptimisticLockException.
>>>>>
>>>>>
>>>>>
>>>>> dezzio wrote:
>>>>>> Hi Philip,
>>>>>>
>>>>>> When two transactions read the same version of AccountSummary, both
>>>>>> cannot successfully update its sum.  Only one will successfully
>>>>>> commit.
>>>>>>
>>>>>> David
>>> 
>>> 
>> 
>> 
> 
> 

-- 
View this message in context: 
http://n2.nabble.com/Is-the-implementation-of-lock%28LockModeType.READ%29-correct--tp2272546p2330901.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.

Reply via email to