简体   繁体   中英

Deleting within a google datastore transaction

I'm testing out Google Datastore to see if I can use it for a queue. Since there are multiple workers pulling off the queue, I'm trying to see how to use Transactions.

In this code, I'm simulating 10 clients all querying for the next job ID, and deleting it.

I receive this error - will this not work with datastore?

Error: 10 ABORTED: too much contention on these datastore entities. please try again.

const ids = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

// await insertion of 10 records
await Promise.all(ids.map(async (id) => {
    let key = datastore.key(['Task', id]);
    let data = {id, queued_at: new Date().toISOString()};
    return datastore.save({key, data});
}));

// await 10 transactions trying to pull and delete from the same queue
await Promise.all(ids.map(async () => {
    const transaction = datastore.transaction();
    await transaction.run();
    const query = transaction
        .createQuery('Task')
        .order('queued_at', {
            descending: false,
        });

    const [results] = await transaction.runQuery(query);
    const result = results[0];

    if (result && result.id) {
        console.log(`deleting ${result.id}`);
        transaction.delete(datastore.key(['Task', result.id]));
    }
    transaction.commit();
    return result && result.id;
}));

You are running up against the Enitity write limits for Datastore:

https://cloud.google.com/datastore/docs/best-practices#entities

In general using this kind of database as an ordered queue is considered an anti- pattern, since both the enqueueing and dequeuing operations end up hotspotting a particular key range. If you need asynchronous processing of transactionally enqueued tasks, consider using Task Queues.

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