How to roll back transactional with save point

hi, i have a code :

  $tblarsiptrxsortirdata->getConnection()->begin(); 
             $tblarsiptrxsortirdata->getConnection()->enableSavePoints(true);       
             $datamasuk = 0;   
             $dataperiodefile = $tbltrxsortidata->findBySesi_periode($sesi_periodeclose)
                     ->selectAllExcept($tbltrxsortidata, ['id','created','modified'])
                     ->enableHydration(false)->toArray();   
             if(!empty($dataperiodefile)){
                   $fixdatatrxmasuk = $tblarsiptrxsortirdata->newEntities($dataperiodefile);
                   try{
                      $tblarsiptrxsortirdata->getConnection()->transactional(function ($connection) use ($tblarsiptrxsortirdata, $fixdatatrxmasuk) {
                              $tblarsiptrxsortirdata->saveMany($fixdatatrxmasuk, ['atomic' => false]);
                      });
                      $info = "Proses Menyusun Periode dan Menggabungkan Sesi Periode File....(".count($dataperiodefile)." File)"; 
                      $numstep = 4;
                      $proses = $stepeksekusi * 10; 
                      $commitarsiptrx = true;
                      $tblarsiptrxsortirdata->getConnection()->commit();  
                      $tblarsiptrxsortirdata->getConnection()->createSavePoint('pointarsiptrx');  
                   } catch (\Cake\ORM\Exception\PersistenceFailedException $e){
                       $tblarsiptrxsortirdata->getConnection()->rollback();  
                   $pesansistem = $e->getMessage();     
                   $info = "Tidak dapat Menyusun File, Membatalkan| $pesansistem";
                   $numstep = 0;
                   $proses = 0; 
                   $rollback = true;
                   }
                }else{
                   $info = "Tidak dapat Menyusun File, Membatalkan";
                   $numstep = 0;
                   $proses = 0; 
                }

How to roll back with name save point for roll back request before

Did you look at this explanation of the transactional() method

It accepts a callable as an argument and will rollback everything inside that callable if a false or exception is returned.

Seems like it should work in your case.

1 Like

thank you, so in transactional for execution can work just one moment, try and catch, if had been exection and success the transactional cannot roll back right ?, in my case, more than execution transactional with rule, if > second 2nd transactional fail lets roll back first 1st transaction or roll back all transactional,

transactional() accepts a callable as its one parameter.

If the callable returns false, all database changes that were attempted inside the callable will be rolled back.

In this example both saves will succeed or both will fail:

$transction = $this->SomeTable->getConnection()
    ->transactional(
        function() use ($entities, $other_entities) {
            $result = $this->SomeTable->save($entities);
            if($result) {
                $result = $this->DifferentTable->save($other_entities);
            }
            return $result;
        }
    );

Also, if the callable throws an exception, all database changes attempted in the callable will roll back. The use of a try/catch block is not required for this to work, but it’s likely you will want to catch the exception for your own reasons.

Something to watch out for

In one complicated case I wrote, I saved some data, then did a query to gather data for additional saves in the callable. I had forgotten my query was inside the callable so the transaction had not yet been committed. This meant the newly ‘saved’ data was not yet in the database! My query did not produce the expected result because of this.

You may not need it, but here is the php documentation on callables.