0

I would like to ask about the concept, so pseudo-code or example in your preferred language should be enough.

Problem:

Let's say, I have two entities. Order and OrderItem. Order has many OrderItems. Let's say, customer calls to helpdesk to change their order for them - maybe they want to change shipping address or add/delete few items. So helpdesk worker needs to be able to change order in the system.

I recently came up with a solution, which solves the problem, but is quite verbouse, hard to debug and silly.

class UpdateOrderDto {
    id: int
    shippingAddress: Address
    items: UpdateOrderItemDto[]
    updatedAt: string // Timestamp
}

class UpdateOrderItemDto {
    id?: int // optional - in case of creating a new item
    productId: int
    quantity: int

    // Flags:
    wasCreated: boolean
    wasUpdated: boolean
    wasDeleted: boolean
}

This data comes in API request. UpdatedAt is used to check optimistic lock. Flags in OrderItem object indicates the action, which happened on item during update.

Then I run something like this on route:

updateOrder(dto: UpdateOrderDto) {
    const orderEntity = this.db.get(dto.id)

    if (orderEntity.updatedAt !== dto.updatedAt)
        throw "Timestamps don't match"

    this.db.startTransaction()

    orderEntity.shippingAddress = dto.shippingAddress
    // ...
    orderEntity.save()

    const itemsToDelete = dto.items.filter(...)
    const itemsToUpdate = dto.items.filter(...)
    const itemsToCreate = dto.items.filter(...)

    for (const item of itemsToDelete) {
        ...
    }
    // ... cycles for each case.

    this.db.endTransaction()
}

Real implementation is much more complex. Would like to ask then, if you know a simpler solution or if I'm missing something. Thank you very much.

Mikeee
  • 85
  • 2
  • 8
  • What is the specific question? You are showing a data model in a programming language, that seems to represent the transaction nature of the order change. However, many markets don't store the details of the change, but only the *current/last* status of the order. It seems the model is OK, but it would be better to include the specific database model as well. – The Impaler Sep 07 '21 at 01:55
  • Also, you seem to have a programming model for optimistic locking, but you are not implementing it in the code. – The Impaler Sep 07 '21 at 01:57
  • @TheImpaler well I tried to find a good example, but need a more general solution (I got quite a few modules with the same problem). I will edit my post to provide a schema. – Mikeee Sep 07 '21 at 07:16
  • `if (orderEntity.updatedAt !== dto.updatedAt)` -- This is not how optimistic locking is implemented. It's part of the `UPDATE` statement. – The Impaler Sep 07 '21 at 16:47
  • @TheImpaler Well I tried to research more into this topic as I'm new to it, but wasn't able to find any good resources - so came with this naive "solution". Could you please direct me somewhere I could learn more? – Mikeee Sep 08 '21 at 17:46
  • In optimistic locking the `save()` operation issues a modified `UPDATE` statement according to some configuration somewhere. I don't know what persistence framework you are using, but all work the same way. The answer to the following question explains the optimistic locking quite well: https://stackoverflow.com/questions/129329/optimistic-vs-pessimistic-locking – The Impaler Sep 08 '21 at 19:13

0 Answers0