Skip to content

fix: make sure reads happen in transaction if there is a transaction#395

Merged
chrisrossi merged 3 commits intogoogleapis:masterfrom
chrisrossi:fix-394
Apr 23, 2020
Merged

fix: make sure reads happen in transaction if there is a transaction#395
chrisrossi merged 3 commits intogoogleapis:masterfrom
chrisrossi:fix-394

Conversation

@chrisrossi
Copy link
Contributor

Fixes a bug where reads during a transaction wouldn't necessarily happen
in the context of the transaction.

Fixes #394

Fixes a bug where reads during a transaction wouldn't necessarily happen
in the context of the transaction.

Fixes googleapis#394
@chrisrossi chrisrossi requested a review from cguardia April 23, 2020 18:07
@googlebot googlebot added the cla: yes This human has signed the Contributor License Agreement. label Apr 23, 2020
Copy link
Contributor

@cguardia cguardia left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great, thanks.

@chrisrossi chrisrossi merged commit f32644f into googleapis:master Apr 23, 2020
@chrisrossi chrisrossi deleted the fix-394 branch April 23, 2020 19:31
@zyzniewski
Copy link
Contributor

zyzniewski commented Apr 29, 2020

Thanks @chrisrossi but it still does not work. Please change in your unittest scenario:

yield [
    update(id, 100, 0.01),
    update(id, 100, 0.00),
]

here comes the professional illustration of the problem:

  • READ1
  • READ2
  • WRITE2
  • WRITE1

WRITE1 should fail and the whole transaction replayed

Thanks!

@chrisrossi
Copy link
Contributor Author

I am looking at it again on master, have moved the delay to the first update call and even made it longer, and I am seeing the expected behavior, exactly as you say it should be. Are you sure you're testing with the fix?

@zyzniewski
Copy link
Contributor

pip install git+https://github.com/googleapis/python-ndb.git@release-v1.2.1 --upgrade
ndb.__version__ == 1.2.1

@zyzniewski
Copy link
Contributor

zyzniewski commented Apr 29, 2020

here's the full example I am using

from google.cloud import ndb

class Simple(ndb.Model):
    foo = ndb.IntegerProperty()

@ndb.transactional_tasklet()
def update(add, delay):

    entity = yield Simple.get_by_id_async('one')

    foo = entity.foo
    foo += add

    yield ndb.sleep(delay)

    entity.foo = foo

    yield entity.put_async()

client = ndb.Client()

@ndb.tasklet
def concurrent_tasks():
    yield [
        update(100, 0.01),
        update(100, 0.00),
    ]

with client.context():

    Simple(id='one', foo=42).put()

    concurrent_tasks().get_result()

    entity = Simple.get_by_id('one', use_cache=False)

    assert entity.foo == 242

@zyzniewski
Copy link
Contributor

Fired it couple times and it's not deterministic

@chrisrossi
Copy link
Contributor Author

I think we've hit a problem with caching....

@chrisrossi
Copy link
Contributor Author

I'm going to open back up the original ticket. This PR does fix a problem that prevented this from working, but there is also interaction with the cache which can prevent it from working as well, which should be dealt with as well, but separately from this fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cla: yes This human has signed the Contributor License Agreement.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Transactions do not work

4 participants