baopham / laravel-dynamodb

Eloquent syntax for DynamoDB
https://packagist.org/packages/baopham/dynamodb
MIT License
490 stars 127 forks source link

Concurrent updates #233

Closed jlefebvre1997 closed 3 years ago

jlefebvre1997 commented 3 years ago

Hello there,

My problem is the following :

If I update different properties of the same object at the same time, one of those properties appear to not be updated at all. For example, if I do

$obj->a = 1;
$obj->save();

and at the same time

$obj->b = 2;
$obj->save();

Sometimes $obj->a is not updated, sometimes it's $obj->b.

Is there a solution on the Bundle's level ? I'm just curious

Thanks for your time and help :)

jlefebvre1997 commented 3 years ago

Ok I found something interesting :

This issue does not happen when using the Query Builder. What's the technical difference between

$item->update([...]);

and


DynamoDb::table('...')->set...(...)->prepare()->updateItem()
``` ? 
jlefebvre1997 commented 3 years ago

Found it ! I didn't know this ORM used putItem even when I simply update an item :( So, next question : is there some way I can prevent update if item has changed on Dynamo's side ? Or event better, can I use updateItem instead of putItem with default save() method ?

zoe-edwards commented 3 years ago

Sadly this is a restriction of the way DynamoDB works and the way that Eloquent works. This is a compromise, as most of the time save() is fine.

I actually use this method for updating items quickly, but note that it does not update the model.

use BaoPham\DynamoDb\Facades\DynamoDb;

public function setAttribute(string $key, string $attribute, $value)
{
    $result = DynamoDb::table($this->tableName)
        ->setKey(DynamoDb::marshalItem(['id' => $key]))
        ->setUpdateExpression('SET #a = :v')
        ->setExpressionAttributeName('#a', $attribute)
        ->setExpressionAttributeValue(':v', DynamoDb::marshalValue($value))
        ->setReturnValues('ALL_NEW')
        ->prepare()
        ->updateItem();

    return $result->get('Attributes');
}

But otherwise it would require a complete change of direction for this package, which isn’t something we can do sadly.

Hope that helps!