简体   繁体   中英

How can I, inside a transaction, read an entity that I just wrote?

I am using Python2.7, GAE and High Replication datastore. I am trying to perform a transaction that first writes an entity and then reads it but the reading never finds the entity. This is a testcase I have:

class DemoTestCase(unittest.TestCase):
  def setUp(self):
    self.testbed = testbed.Testbed()
    self.testbed.activate()
    self.policy = datastore_stub_util.PseudoRandomHRConsistencyPolicy(probability=0)
    self.testbed.init_datastore_v3_stub(consistency_policy=self.policy)

  def tearDown(self):
    self.testbed.deactivate()

  def test1(self):
    db.run_in_transaction(self._write)
    db.run_in_transaction(self._read)

  def test2(self):
    db.run_in_transaction(self._write_read)

  def _write(self):
    self.root_key = db.Key.from_path("A", "root")
    a             = A(a=1, parent=self.root_key)
    self.a_key    = a.put()

  def _read(self):
    b = sample.read_a(self.a_key)
    self.assertEqual(1, b.a)
    self.assertEqual(1, A.all().ancestor(self.root_key).count(5))

  def _write_read(self):
    root_key = db.Key.from_path("A", "root")
    a     = A(a=1, parent=root_key)
    a_key = a.put()
    b     = sample.read_a(a_key)
    self.assertEqual(None, b)
    self.assertEqual(0, A.all().ancestor(root_key).count(5))

Both testcases are passing now.

Test1 is running a transaction which performs a write. Then it's running a second transaction that performs two reads, one by key and one by ancestor-query. Reads work just fine in this case.

Test2 is running exactly the same code as test1, but this time everything gets run inside the same transaction. As you can see, reading the entity by key returns None. Doing a ancestor query returns 0 hits.

My question is: how can I, inside a transaction, read an entity that I just wrote? Or is this not possible?

Thanks.

You can't. All datastore reads inside the transaction show a snapshot of the datastore when the transaction started. Writes don't show up.

Theoretically, you shouldn't have to read, since you will have an instance of every entity your write. Use that instance.

Well, sometimes it's really helpful to re-read. A business rule may be triggered by the entity update and will need to reload it. BRs often are not aware of what triggered them and won't have immediate access to the new entity.

Don't know for Python but, in Java using Objectify, updates are made visible while in the transaction by Objectify session (transaction) cache. If there's something like a session cache in the Python persistence framework you are using, that may be a solution.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM