Tip: Use transactions to handle complex logic

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • alter
    Member
    • Apr 2018
    • 57

    Tip: Use transactions to handle complex logic

    Hi, I would like mention some advantages of developing code within the so-called transaction, which is available in EspoCRM via Transaction Manager.

    What is a transaction in terms of development?
    - The answer is very simple. Transaction is a "container", or "set" of logic operations, which are executed one after another with let's say "promise" to complete all the requests successfully, or not complete any request at all.

    So basically it's "all or nothing".

    Why would you want to use transaction in EspoCRM?

    Let's say you have a complex logic in code, something like:
    1) Retrieve related record
    2) List all related entites via 1:N relationship
    3) Foreach related entity perform retrieve of related entity
    4) For each entity call external API and retrieve some value and set it on the entity
    5) Set the value to that entity in EspoCRM
    6) Set value on previous entity
    etc...

    Let's say this logic is more complex than just retrieve value and set value on a simple record.

    If you would use common way to approach it, you would simply create a afterSave hook for example, that would fire the 1), then 2) etc.

    The main difference between transaction and the common way is, that if you will not use transaction in this logic and the code fails at 5) or 6), the code before it will still be executed.

    On the other hand, if you would use transcation, and the code would fail even on 20) for example, all the actions performed before 20) would be rollbackem as it would never been executed. All or nothing -> either all the logic of the code will be successfull, or everything will be rollbacked and not a single action will be performed.

    Mostly the transactions are used when you have a bit more complex code and you are retrieving and mainly settings the values on more records etc. -> because sometimes it doesn't make sense to set some value, if the code fails in next step of setting some other value to related record etc.

    On the other hand, I like to use transactions almost every time, because I see the code as a logical container of business requirements and usually all the steps in code are important, so I tend to use the transaction a lot, because I want all the logic of the code be sucessfull, or rollback everything, log error and solve the issue etc.

    How to use transaction?

    Very simple, just use the transaction manager in you code, something like:

    PHP Code:
    ... constructors, override methods etc..
    
    public function doMyLogic(EntityManager $entityManager, Logger $logger)
    {
    $transactionManager = $entityManager->getTransactionManager();
    
    $transactionManager->start();
    try {
    // 1)
    // 2)
    // 3)
    // etc..
    $transactionManager->commit();
    }
    catch (Exception $ex)
    {
    logger.logError($ex->getMessage());
    $transactionManager->rollback();
    }
    } 
    
    More ways how to use the transactions: https://docs.espocrm.com/development...action-manager
  • item
    Active Community Member
    • Mar 2017
    • 1476

    #2
    Nice,

    one question : i "create/find/relate/" over 180000 records each month.. the jobs take +- 4hours (VPS on the cloud) (i have tested on ours server VPS "20minutes") ..

    do you think i can use "transactionManager" ? There are a limit ? Maybe Yuri know that.

    If you could give the project a star on GitHub. EspoCrm believe our work truly deserves more recognition. Thanks.​

    Comment

    • alter
      Member
      • Apr 2018
      • 57

      #3
      Hi, I believe that should not be a problem. If it works now, it should work within transaction as well. But keep in mind, if the jobs is creating +- 180000 records and you will use the transaction and there would happen some error at 175000th record for example, every create/update/find/relate action on those 174999 would be rollbacked and I am not sure if you would want it - if you would use the transaction on the wrong place. Use transaction on the logic you want to be completed for the specific record, do not put the whole logic there, or it would end like I described

      Comment

      • item
        Active Community Member
        • Mar 2017
        • 1476

        #4
        Hi,
        yes i think like you describe..
        i know in the past, (180000records is in a CSV).. so i read each line, and make logic.. but when "mysql sever go away error", then the CSV is re-inserted from begining

        I can't mass insert in db like https://docs.espocrm.com/development/orm/#mass-insert , i can't read a CSV of 50M in one time and relate/find/update..

        i have put a "ini_set('memory_limit',0);" on the beginning of jobs.. since 2years no issues. (je croise le doigts)

        but just by curiosity, there are certainly a limit in transaction... or where mysql store this data before commit ? temporary table ?

        If you could give the project a star on GitHub. EspoCrm believe our work truly deserves more recognition. Thanks.​

        Comment

        • alter
          Member
          • Apr 2018
          • 57

          #5
          Hi, only limits should be at infrastructure layer -> mainly on the machine the database is running (RAM, CPU etc.). Transactions are usually used even with millions of records, so it should not be a problem. I think the data might be stored in some temporary DB, or in cache/RAM allocation or something like that.

          Comment

          Working...