[ 
https://issues.apache.org/jira/browse/SENTRY-1486?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15678068#comment-15678068
 ] 

Alexander Kolbasov commented on SENTRY-1486:
--------------------------------------------

Here is a bit more explanation for the problem with read-committed transaction 
isolation level.
I wrote a little test that demonstrates the problem. 

Here is the description of the test:

test creates 10 persistent instances of class Product each having a price of 
$10.
It also  creates two threads running in parallel. 
The first thread simulates a typical Sentry workflow. It walks all rows one by 
one and adds the price together, printing each product as it goes and the final 
total price (which should be $100)
The second thread simulates updates. It walks all products and for each even 
one it increases its price by $5 and for each odd one it decreases it by $5. 
This doesn't change the total price, of course.
As expected, running this program produces different results from one run to 
another. Sometimes I get total of 100 and sometimes 95. So the behavior is 
non-deterministic. The problem is that "read-committed" transactions do not 
prevent any changes happening between statements within transaction.

This means that in the presence of writes Sentry may produce non-deterministic 
results which is rather bad.

Here are code snippets:
{code}
public double total(PersistenceManager pm) {
    double result = 0.0;
    Transaction tx = pm.currentTransaction();
    tx.begin();
    for (int i = 0; i < nobjects; i++) {
        Query<Product> query = pm.newQuery(Product.class);
        query.setFilter("this.pid == :pid");
        query.setUnique(true);
        Product p = (Product)query.execute(i);
        result += p.getPrice();
        System.out.println(p);
    }
    tx.commit();

    return result;
}
{code}
public void updatePrice(PersistenceManager pm) {
    Transaction tx = pm.currentTransaction();
    tx.begin();
    // for (int i = 0; i < nobjects; i++) {
    for (int i = 0; i < nobjects; i++) {
        Product p = (Product) pm.getObjectById(prodIds[i]);
        if (i % 2 == 0) {
            p.updatePrice(5.0);
        } else {
            p.updatePrice(-5.0);
        }
    }
    tx.commit();
}
{code}
And here are a some test runs:
Run 1:
{code}
Product(11) name=Product0 [Some product] pid = 0 price 10.0
Product(12) name=Product1 [Some product] pid = 1 price 5.0
Product(13) name=Product2 [Some product] pid = 2 price 15.0
Product(14) name=Product3 [Some product] pid = 3 price 5.0
Product(15) name=Product4 [Some product] pid = 4 price 15.0
Product(16) name=Product5 [Some product] pid = 5 price 5.0
Product(17) name=Product6 [Some product] pid = 6 price 15.0
Product(18) name=Product7 [Some product] pid = 7 price 5.0
Product(19) name=Product8 [Some product] pid = 8 price 15.0
Product(20) name=Product9 [Some product] pid = 9 price 5.0
-> 1_1: 95.0000
{code}
Run 2:
{code}
Product(21) name=Product0 [Some product] pid = 0 price 10.0
Product(22) name=Product1 [Some product] pid = 1 price 10.0
Product(23) name=Product2 [Some product] pid = 2 price 15.0
Product(24) name=Product3 [Some product] pid = 3 price 5.0
Product(25) name=Product4 [Some product] pid = 4 price 15.0
Product(26) name=Product5 [Some product] pid = 5 price 5.0
Product(27) name=Product6 [Some product] pid = 6 price 15.0
Product(28) name=Product7 [Some product] pid = 7 price 5.0
Product(29) name=Product8 [Some product] pid = 8 price 15.0
Product(30) name=Product9 [Some product] pid = 9 price 5.0
-> 1_1: 100.000
{code}

> Sentry should use repeatable-read consistency level
> ---------------------------------------------------
>
>                 Key: SENTRY-1486
>                 URL: https://issues.apache.org/jira/browse/SENTRY-1486
>             Project: Sentry
>          Issue Type: Bug
>          Components: Sentry
>    Affects Versions: 1.7.0, sentry-ha-redesign
>            Reporter: Alexander Kolbasov
>            Assignee: Alexander Kolbasov
>             Fix For: 1.8.0
>
>         Attachments: SENTRY-1486.001.patch, SENTRY-1486.002.patch
>
>
> Currently Sentry uses the "read-committed" consistency level which is the 
> default for the Datanucleus JDO library. This causes potential problems since 
> the state visible to each transaction can actually see updates from another 
> transactions, so it is very difficult to reason about any code that reads 
> multiple pieces of data.
> Instead it should use repeatable read" consistency which guarantees that any 
> transaction only sees the state at the beginning of a transaction plus any 
> updates done within a transaction.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to