/**
  * @see SubscriptionManager::unsubscribe
  *
  * @param string $subscriber Global site ID of the client
  * @param EntityId[] $entityIds The entities to subscribe to.
  *
  * @throws InvalidArgumentException
  * @throws UsageTrackerException
  * @throws Exception
  */
 public function unsubscribe($subscriber, array $entityIds)
 {
     if (!is_string($subscriber)) {
         throw new InvalidArgumentException('$subscriber must be a string.');
     }
     $unsubscriptions = $this->idsToString($entityIds);
     $db = $this->connectionManager->beginAtomicSection(__METHOD__);
     try {
         $oldSubscriptions = $this->querySubscriptions($db, $subscriber, $unsubscriptions);
         $obsoleteSubscriptions = array_intersect($unsubscriptions, $oldSubscriptions);
         $this->deleteSubscriptions($db, $subscriber, $obsoleteSubscriptions);
         $this->connectionManager->commitAtomicSection($db, __METHOD__);
     } catch (Exception $ex) {
         $this->connectionManager->rollbackAtomicSection($db, __METHOD__);
         if ($ex instanceof DBError) {
             throw new UsageTrackerException($ex->getMessage(), $ex->getCode(), $ex);
         } else {
             throw $ex;
         }
     }
 }
 public function testRollbackAtomicSection()
 {
     $connection = $this->getConnectionMock();
     $lb = $this->getLoadBalancerMock();
     $lb->expects($this->once())->method('reuseConnection')->with($connection)->will($this->returnValue(null));
     $connection->expects($this->once())->method('rollback')->will($this->returnValue(null));
     $manager = new ConsistentReadConnectionManager($lb);
     $manager->rollbackAtomicSection($connection, 'TEST');
 }