You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@sentry.apache.org by "Alexander Kolbasov (JIRA)" <ji...@apache.org> on 2016/11/18 23:13:58 UTC

[jira] [Commented] (SENTRY-1486) Sentry should use repeatable-read consistency level

    [ 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)