public function testRollbackWithBadTransaction2() { $response = new Response(); $response->add('spanner', new Base($this->entityManager->recordManager), Response::SUCCESS); $response->add('monkey', new Base($this->entityManager->recordManager), Response::SUCCESS); $this->setExpectedException('Bond\\RecordManager\\Exception\\TransactionDoesNotExistException'); $response->rollback('not a valid transaction'); }
/** * Add a item to the queue for persitance on flush * * @param $trancation * @param $onFailure * * @return bool */ public function flush($transaction = null, $onFailure = self::FLUSH_ABORT, $throwExceptions = true) { if (is_null($transaction)) { $transaction = self::TRANSACTIONS_ALL; } if (is_null($onFailure)) { $onFailure = self::FLUSH_ABORT; } $response = new Response(); $exceptions = []; $haveAnyTransactionsFailed = false; // simulate $simulate = $this->debug & self::DEBUG_SIMULATE; // profiler $profiler = new Profiler("Record manager"); $profiler->log(); // debugging query show $debugQuery = null; if ($this->debug & self::DEBUG_SHOW_QUERY) { $debugQuery = function ($e, $event, $data) { echo $data . "\n"; }; $this->db->debug->on(Debug::INFO, $debugQuery); } // trap all throw exceptions so that we can properly unattach the $db->debug->on( Pg::QueryPassed $listener ) try { // iterate selected transactions foreach ($this->getQueue($transaction, true, true) as $transaction => $queue) { unset($this->queue[$transaction]); $taskResponse = null; $hasTransactionFailed = false; $beginTransaction = new Query("BEGIN TRANSACTION READ WRITE; /* %transaction:% */"); $beginTransaction->transaction = $transaction; $this->db->query($beginTransaction); $this->eventEmitter->emit(EventEmitter::TRANSACTION_START, $this, $transaction, $queue); // loop over our tasks foreach ($queue as $task) { // are we continuing to process? if ($hasTransactionFailed or $haveAnyTransactionsFailed && $onFailure === self::FLUSH_ABORT) { $taskResponse = Response::ABORTED; } else { try { $taskResponse = $task->execute($this->db, $simulate) ? Response::SUCCESS : Response::FAILED; } catch (\Exception $e) { // It'd be nice if we could just test for Query exceptions here but unfortunately PHPUnit dicks pretty hard with exception types. // @Mr Beale. I realise this violates the "only handle exceptions that you understand" rule but I can't find a way round this. Pete $taskResponse = $e; $exceptions[] = $e; } } // transaction success if ($taskResponse !== Response::SUCCESS) { $hasTransactionFailed = true; $haveAnyTransactionsFailed = true; } $response->add($transaction, $task, $taskResponse); } // end or rollback transaction $endTransaction = new Query("%commitOrRollback:% TRANSACTION; /* %transaction:% */"); $endTransaction->commitOrRollback = new Raw($hasTransactionFailed ? 'ROLLBACK' : 'COMMIT'); $endTransaction->transaction = $transaction; $this->db->query($endTransaction); // response rollback if ($hasTransactionFailed) { $response->rollback($transaction); } $profiler->log($transaction); } // if we've gathered any exceptions throw them here if ($throwExceptions and $exceptions) { throw $exceptions[0]; } $response->profilerAssign($profiler); } catch (\Exception $e) { $this->db->debug->removeListener(Pg::QUERY_PARSED, $debugQuery); throw $e; } return $response; }