antonioribeiro / tracker

Laravel Stats Tracker
MIT License
2.9k stars 597 forks source link

Error in Laravel 8 migration problem, There is no active transaction #532

Open pishguy opened 3 years ago

pishguy commented 3 years ago

after installing this package and define settings into app/config.php and publishing configuration, when i try to run this command:

php artisan migrate:fresh 

i get error after this part of readme install document

Migrate it

If you have set the default connection to tracker, you can:
php artisan migrate

Error:

Migrating: 2014_10_12_100000_create_password_resets_table
Migrated:  2014_10_12_100000_create_password_resets_table (43.99ms)
Migrating: 2015_03_07_311070_create_tracker_paths_table

   PDOException 

  There is no active transaction

  at vendor/laravel/framework/src/Illuminate/Database/Concerns/ManagesTransactions.php:189
    185▕      */
    186▕     public function commit()
    187▕     {
    188▕         if ($this->transactions == 1) {
  ➜ 189▕             $this->getPdo()->commit();
    190▕ 
    191▕             optional($this->transactionsManager)->commit($this->getName());
    192▕         }
    193▕ 

      +35 vendor frames 
  36  artisan:37
      Illuminate\Foundation\Console\Kernel::handle()

I'm using Docker as LaraDock and this is my database file content:

<?php

use Illuminate\Support\Str;

return [

    'default' => env('DB_CONNECTION', 'mariadb'),

    'connections' => [

        ///
        'tracker' => [
            'driver'   => 'mysql',
            'host' => env('DB_HOST', 'mariadb'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE', 'forge'),
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'charset' => 'utf8mb4',
            'strict' => false,
            'collation' => 'utf8mb4_persian_ci',
        ],
        'mysql' => [
            'driver' => 'mysql',
            'url' => env('DATABASE_URL'),
            'host' => env('DB_HOST', 'mariadb'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE', 'forge'),
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'unix_socket' => env('DB_SOCKET', ''),
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_persian_ci',
            'prefix' => '',
            'prefix_indexes' => true,
            'strict' => true,
            'engine' => null,
            'options' => extension_loaded('pdo_mysql') ? array_filter([
                PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
            ]) : [],
        ],

        ///

        'laravel-visits' => [
            'host' => env('REDIS_HOST', '127.0.0.1'),
            'password' => env('REDIS_PASSWORD', null),
            'port' => env('REDIS_PORT', 6379),
            'database' => 3, // anything from 1 to 15, except 0 (or what is set in default)
        ],

    ],
    'migrations' => 'migrations',

    /

    ///

    ],

];
sevakode commented 3 years ago

Hello

after installing this package and define settings into app/config.php and publishing configuration, when i try to run this command:

php artisan migrate:fresh 

i get error after this part of readme install document

Migrate it

If you have set the default connection to tracker, you can:
php artisan migrate

Error:

Migrating: 2014_10_12_100000_create_password_resets_table
Migrated:  2014_10_12_100000_create_password_resets_table (43.99ms)
Migrating: 2015_03_07_311070_create_tracker_paths_table

   PDOException 

  There is no active transaction

  at vendor/laravel/framework/src/Illuminate/Database/Concerns/ManagesTransactions.php:189
    185▕      */
    186▕     public function commit()
    187▕     {
    188▕         if ($this->transactions == 1) {
  ➜ 189▕             $this->getPdo()->commit();
    190▕ 
    191▕             optional($this->transactionsManager)->commit($this->getName());
    192▕         }
    193▕ 

      +35 vendor frames 
  36  artisan:37
      Illuminate\Foundation\Console\Kernel::handle()

I'm using Docker as LaraDock and this is my database file content:

<?php

use Illuminate\Support\Str;

return [

    'default' => env('DB_CONNECTION', 'mariadb'),

    'connections' => [

        ///
        'tracker' => [
            'driver'   => 'mysql',
            'host' => env('DB_HOST', 'mariadb'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE', 'forge'),
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'charset' => 'utf8mb4',
            'strict' => false,
            'collation' => 'utf8mb4_persian_ci',
        ],
        'mysql' => [
            'driver' => 'mysql',
            'url' => env('DATABASE_URL'),
            'host' => env('DB_HOST', 'mariadb'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE', 'forge'),
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'unix_socket' => env('DB_SOCKET', ''),
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_persian_ci',
            'prefix' => '',
            'prefix_indexes' => true,
            'strict' => true,
            'engine' => null,
            'options' => extension_loaded('pdo_mysql') ? array_filter([
                PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
            ]) : [],
        ],

        ///

        'laravel-visits' => [
            'host' => env('REDIS_HOST', '127.0.0.1'),
            'password' => env('REDIS_PASSWORD', null),
            'port' => env('REDIS_PORT', 6379),
            'database' => 3, // anything from 1 to 15, except 0 (or what is set in default)
        ],

    ],
    'migrations' => 'migrations',

    /

    ///

    ],

];

Hello, your have found a solved to the problem?

pishguy commented 3 years ago

@HDsouls not yet, i think this package is not available for php 8 or laravel 8

ingoldsby commented 3 years ago

You can 'fix' this by updating some code in PragmaRX\Support\Migration

The issue is with PHP8 and PDO transaction stuff. The original code of the 'executeInTransaction' function needs to be amended. The original code is:

/**
     * Execute the migrationm command inside a transaction layer.
     *
     * @param $method
     */
    protected function executeInTransaction($method)
    {
        $this->connection->beginTransaction();

        try 
        {
            $this->{$method}();
        } 
        catch (\Exception $exception)
        {
            $this->connection->rollback();

            $this->handleException($exception);
        }

        $this->connection->commit();
    }

Change the last bit to:

        if ($this->connection->getPdo()->inTransaction()) {
            $this->connection->commit();
        }

It works for me but I haven't tested it more broadly.

Xevrac commented 3 years ago

Thanks for the tip @ingoldsby - Have you had any side affects from this in the last 15 days? Or noticed any other issues abroad

ingoldsby commented 3 years ago

I'm not sure if it was related or not, but I had some session_start() issues when I pushed it to AWS from local computer. So I took it off for now until I get time to investigate more.

rohanshukla94 commented 3 years ago

Check if your php.ini file has php_pdo extension enabled. I am trying this on Laravel 8.44 and it migrated the migration files. I got the blade files through git checkout and opened Stats route which now only gives me Datatables error.

PS I did not follow @ingoldsby 's advice

rohanshukla94 commented 3 years ago

Screenshot from 2021-06-03 17-10-03

niko-lino commented 3 years ago

Screenshot from 2021-06-03 17-10-03

I have same problem on Laravel 8

ghost commented 3 years ago

You can 'fix' this by updating some code in PragmaRX\Support\Migration

The issue is with PHP8 and PDO transaction stuff. The original code of the 'executeInTransaction' function needs to be amended. The original code is:

/**
   * Execute the migrationm command inside a transaction layer.
   *
   * @param $method
   */
  protected function executeInTransaction($method)
  {
      $this->connection->beginTransaction();

      try 
      {
          $this->{$method}();
      } 
      catch (\Exception $exception)
      {
          $this->connection->rollback();

          $this->handleException($exception);
      }

      $this->connection->commit();
  }

Change the last bit to:

      if ($this->connection->getPdo()->inTransaction()) {
          $this->connection->commit();
      }

It works for me but I haven't tested it more broadly.

Thank you it worked, rather than overwriting the packages I duplicated PragmaRX\Support\Migration locally as a util, applied the changes you suggested, and imported my util in the all the migrations. Hope this helps someone else in the meantime

Xevrac commented 2 years ago

Any negative impact with this popup error? @rohanshukla9

MuturiKimangu commented 2 years ago

after installing this package and define settings into app/config.php and publishing configuration, when i try to run this command:

php artisan migrate:fresh 

i get error after this part of readme install document

Migrate it

If you have set the default connection to tracker, you can:
php artisan migrate

Error:

Migrating: 2014_10_12_100000_create_password_resets_table
Migrated:  2014_10_12_100000_create_password_resets_table (43.99ms)
Migrating: 2015_03_07_311070_create_tracker_paths_table

   PDOException 

  There is no active transaction

  at vendor/laravel/framework/src/Illuminate/Database/Concerns/ManagesTransactions.php:189
    185▕      */
    186▕     public function commit()
    187▕     {
    188▕         if ($this->transactions == 1) {
  ➜ 189▕             $this->getPdo()->commit();
    190▕ 
    191▕             optional($this->transactionsManager)->commit($this->getName());
    192▕         }
    193▕ 

      +35 vendor frames 
  36  artisan:37
      Illuminate\Foundation\Console\Kernel::handle()

I'm using Docker as LaraDock and this is my database file content:

<?php

use Illuminate\Support\Str;

return [

    'default' => env('DB_CONNECTION', 'mariadb'),

    'connections' => [

        ///
        'tracker' => [
            'driver'   => 'mysql',
            'host' => env('DB_HOST', 'mariadb'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE', 'forge'),
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'charset' => 'utf8mb4',
            'strict' => false,
            'collation' => 'utf8mb4_persian_ci',
        ],
        'mysql' => [
            'driver' => 'mysql',
            'url' => env('DATABASE_URL'),
            'host' => env('DB_HOST', 'mariadb'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE', 'forge'),
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'unix_socket' => env('DB_SOCKET', ''),
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_persian_ci',
            'prefix' => '',
            'prefix_indexes' => true,
            'strict' => true,
            'engine' => null,
            'options' => extension_loaded('pdo_mysql') ? array_filter([
                PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
            ]) : [],
        ],

        ///

        'laravel-visits' => [
            'host' => env('REDIS_HOST', '127.0.0.1'),
            'password' => env('REDIS_PASSWORD', null),
            'port' => env('REDIS_PORT', 6379),
            'database' => 3, // anything from 1 to 15, except 0 (or what is set in default)
        ],

    ],
    'migrations' => 'migrations',

    /

    ///

    ],

];

had the same error. Found a work around by editing by editing the commit function. I reduced the transaction count to zero. Was able to seed without error, rolled back the code after I was through. Hope it helps someone.

public function commit()

187▕     {
188▕         if ($this->transactions == 0) {

➜ 189▕ $this->getPdo()->commit(); 190▕ 191▕ optional($this->transactionsManager)->commit($this->getName()); 192▕ }

bradietilley commented 2 years ago

This error can be caused by different things, but ultimately a transaction being committed prematurely.

For me it was the because my base Tests\TestCase was using Illuminate\Foundation\Testing\RefreshDatabase a bunch of children TestCase were using Illuminate\Foundation\Testing\DatabaseMigrations. After removing DatabaseMigrations it works fine.

danshou commented 1 year ago

The solution from @bradietilley worked for me. After doing a little research I found out that RefreshDatabase starts every test with a brand new database and DatabaseMigrations executes a rollback after finishing the test. The second one is unnecessary since every test will start the database as brand new. There was no need for a rollback in my case.