Skip to content

Commit

Permalink
Merge pull request #281 from medic123de/db-transactional-mode
Browse files Browse the repository at this point in the history
Use transactions for Tracking API requests in bulk. fixes #5275

Thanks for the pull request, it's an Awesome Performance Improvement!
  • Loading branch information
Matthieu Aubry committed Jun 2, 2014
2 parents c18c274 + 96036df commit 657a35e
Show file tree
Hide file tree
Showing 4 changed files with 161 additions and 1 deletion.
4 changes: 4 additions & 0 deletions config/global.ini.php
Expand Up @@ -524,6 +524,10 @@
; Whether Bulk tracking requests to the Tracking API requires the token_auth to be set.
bulk_requests_require_authentication = 0

; Whether Bulk tracking requests will be wrapped within a DB Transaction.
; This greatly increases performance of Log Analytics and in general any Bulk Tracking API requests.
bulk_requests_use_transaction = 1

; Comma separated list of known Referrer Spammers, ie. bot visits that set a fake Referrer field.
; All Visits with a Referrer URL host set to one of these will be excluded.
; If you find new spam entries in Referrers>Websites, please report them here: http://dev.piwik.org/trac/ticket/5099
Expand Down
49 changes: 48 additions & 1 deletion core/Tracker.php
Expand Up @@ -193,7 +193,6 @@ private function authenticateBulkTrackingRequests($rawData)
}

if (!empty($this->requests)) {

foreach ($this->requests as &$request) {
// if a string is sent, we assume its a URL and try to parse it
if (is_string($request)) {
Expand Down Expand Up @@ -236,18 +235,23 @@ public function main($args = null)
$this->initOutputBuffer();

if (!empty($this->requests)) {
$this->beginTransaction();

try {
foreach ($this->requests as $params) {
$isAuthenticated = $this->trackRequest($params, $tokenAuth);
}
$this->runScheduledTasksIfAllowed($isAuthenticated);
$this->commitTransaction();
} catch(DbException $e) {
Common::printDebug($e->getMessage());
$this->rollbackTransaction();
}

} else {
$this->handleEmptyRequest(new Request($_GET + $_POST));
}

$this->end();

$this->flushOutputBuffer();
Expand All @@ -268,6 +272,47 @@ protected function getOutputBuffer()
return ob_get_contents();
}

protected function beginTransaction()
{
$this->transactionId = null;
if(!$this->shouldUseTransactions()) {
return;
}
$this->transactionId = self::getDatabase()->beginTransaction();
}

protected function commitTransaction()
{
if(empty($this->transactionId)) {
return;
}
self::getDatabase()->commit($this->transactionId);
}

protected function rollbackTransaction()
{
if(empty($this->transactionId)) {
return;
}
self::getDatabase()->rollback($this->transactionId);
}

/**
* @return bool
*/
protected function shouldUseTransactions()
{
$isBulkRequest = count($this->requests) > 1;
return $isBulkRequest && $this->isTransactionSupported();
}

/**
* @return bool
*/
protected function isTransactionSupported()
{
return (bool) Config::getInstance()->Tracker['bulk_requests_use_transaction'];
}

protected function shouldRunScheduledTasks()
{
Expand Down Expand Up @@ -865,4 +910,6 @@ protected static function getRawBulkRequest()
{
return file_get_contents("php://input");
}


}
56 changes: 56 additions & 0 deletions core/Tracker/Db/Mysqli.php
Expand Up @@ -25,6 +25,8 @@ class Mysqli extends Db
protected $username;
protected $password;
protected $charset;
protected $activeTransaction = false;


/**
* Builds the DB object
Expand Down Expand Up @@ -276,4 +278,58 @@ public function rowCount($queryResult)
{
return mysqli_affected_rows($this->connection);
}

/**
* Start Transaction
* @return string TransactionID
*/

public function beginTransaction()
{
if(!$this->activeTransaction === false ) {
return;
}

if( $this->connection->autocommit(false) ) {
$this->activeTransaction = uniqid();
return $this->activeTransaction;
}
}

/**
* Commit Transaction
* @param string TransactionID from beginTransaction
*/

public function commit($xid)
{
if($this->activeTransaction != $xid || $this->activeTransaction === false ) {

return;
}
$this->activeTransaction = false;

if(!$this->connection->commit() ) {
throw new DbException("Commit failed");
}
$this->connection->autocommit(true);
}

/**
* Rollback Transaction
* @param string TransactionID from beginTransaction
*/

public function rollBack($xid)
{
if($this->activeTransaction != $xid || $this->activeTransaction === false ) {
return;
}
$this->activeTransaction = false;

if(!$this->connection->rollback() ) {
throw new DbException("Rollback failed");
}
$this->connection->autocommit(true);
}
}
53 changes: 53 additions & 0 deletions core/Tracker/Db/Pdo/Mysql.php
Expand Up @@ -30,6 +30,8 @@ class Mysql extends Db
protected $password;
protected $charset;

protected $activeTransaction = false;

/**
* Builds the DB object
*
Expand Down Expand Up @@ -234,4 +236,55 @@ public function rowCount($queryResult)
{
return $queryResult->rowCount();
}

/**
* Start Transaction
* @return string TransactionID
*/

public function beginTransaction()
{
if(!$this->activeTransaction === false ) {
return;
}

if( $this->connection->beginTransaction() ) {
$this->activeTransaction = uniqid();
return $this->activeTransaction;
}
}

/**
* Commit Transaction
* @param string TransactionID from beginTransaction
*/

public function commit($xid)
{
if($this->activeTransaction != $xid || $this->activeTransaction === false ) {
return;
}
$this->activeTransaction = false;

if(!$this->connection->commit() ) {
throw new DbException("Commit failed");
}
}

/**
* Rollback Transaction
* @param string TransactionID from beginTransaction
*/

public function rollBack($xid)
{
if($this->activeTransaction != $xid || $this->activeTransaction === false ) {
return;
}
$this->activeTransaction = false;

if(!$this->connection->rollBack() ) {
throw new DbException("Rollback failed");
}
}
}

0 comments on commit 657a35e

Please sign in to comment.