2016-04-04 4 views
23

Ich habe eine sehr kleine Datenmenge in einer Methode auf einer Test-Klasse generiert wurde, hatte ich versucht, die Daten in der setUp()-Methode erzeugt, aber es führte zu einem Lock Wait Timeout für jeden Test. Es hat ein wenig geholfen, diesen Code aus der setUp()-Methode zu entfernen und in seine eigene Methode zu bringen. Das bedeutet, dass nicht jeder Test sich über die Schlösser beschwert.MySQL Lock Wartezeit Timeout mit Modell Factories

Ich verwende die DatabaseTransactions-Eigenschaft, die in Laravel 5.2 ist, so dass die Datenbank zurückgesetzt wird, bevor jeder Testfall ausgeführt wird.

In jedem Testfall, den ich habe, mache ich einen Anruf, um die Scheindaten so zu bekommen.

$data = self::getRandomCommunityWithAssociatedData(); 

Die tatsächliche Methode generiert nur einige Community-Objekte und Benutzerobjekte für die erstellte Community.

Es gibt einige Konstanten, die in dieser Methode verwendet werden, und sie werden verwendet, um zu bestimmen, wie viele von jedem zu erzeugenden Objekt. Derzeit erstelle ich zwei Communities und drei Benutzer und zwei Admins für jede Community-Instanz.

Die Sperrwartezeitüberschreitungen sind nicht vorhersehbar, ein Lauf konnte im ersten Testfall passieren, ein weiterer Lauf konnte im 5. Testfall passieren.

Ich habe versucht, die Zeit zu erhöhen, in der MySQL auf die Sperre auf 500 Sekunden wartet, und ich bekomme immer noch die Timeouts. Eine Erhöhung dieser Zeit ist keine Option, da die Tests in allen Umgebungen ausgeführt werden müssen.

Irgendwelche Gedanken, warum ich diese Sperren bekommen könnte, warten Timeouts, wenn Sie die DatabaseTransactions-Eigenschaft in Laravel 5.2 mit einem so kleinen Datensatz verwenden?

1) UserEmailNotificationsTest::testActiveAdminReceivesNewCommentEmailNotification 
Illuminate\Database\QueryException: SQLSTATE[HY000]: General error: 1205 Lock wait timeout exceeded; try restarting transaction (SQL: insert into `communities` (` 

Die obige Abfrage, ist ein einfacher Einsatz auf der Community-Tabelle ausgeführt wird, und es gibt keine komplizierten Subqueries oder so etwas in diesen Daten Generation geht.

Aktiviert das Abfrageprotokoll, Ergebnisse.

 30 Query START TRANSACTION 
     30 Query SAVEPOINT trans2 
     30 Prepare insert into `communities` (`viddler_id`, `domain`, `subdomain`, `active`, `max_seats`, `created_at`, `updated_at`, `assignment_seats`, `general_settings`, `access_settings`, `branding_settings`) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) 
     30 Execute insert into `communities` (`viddler_id`, `domain`, `subdomain`, `active`, `max_seats`, `created_at`, `updated_at`, `assignment_seats`, `general_settings`, `access_settings`, `branding_settings`) values ('74', 'gaylord.com', 'qui', '1', '24', '2016-03-30 16:25:45', '2016-04-04 02:27:04', '23', 'a:11:{s:5:\"title\";s:0:\"\";s:11:\"description\";s:0:\"\";s:10:\"meta_title\";s:0:\"\";s:16:\"meta_description\";s:0:\"\";s:13:\"meta_keywords\";s:0:\"\";s:17:\"thumbnail_display\";s:0:\"\";s:18:\"group_nomenclature\";s:8:\"Channels\";s:13:\"home_template\";s:0:\"\";s:11:\"api_version\";s:1:\"2\";s:8:\"language\";s:2:\"en\";s:21:\"use_nested_navigation\";i:0;}', 'a:10:{s:12:\"restrictions\";s:10:\"Restricted\";s:17:\"auto_registration\";i:0;s:14:\"default_active\";i:0;s:12:\"oauth_google\";i:0;s:14:\"oauth_facebook\";i:0;s:14:\"oauth_linkedin\";i:0;s:16:\"oauth_reg_google\";i:0;s:18:\"oauth_reg_facebook\";i:0;s:18:\"oauth_reg_linkedin\";i:0;s:11:\"lti_enabled\";i:0;}', 'a:14:{s:13:\"contact_email\";s:0:\"\";s:17:\"contact_link_text\";s:0:\"\";s:9:\"logo_file\";s:0:\"\";s:14:\"carousel_items\";s:0:\"\";s:11:\"html_header\";s:0:\"\";s:16:\"footer_copyright\";s:45:\"© 2015 Viddler Inc. All Rights Reserved.\";s:19:\"footer_privacy_link\";s:37:\"http://www.viddler.com/privacy-policy\";s:17:\"footer_terms_link\";s:35:\"http://www.viddler.com/terms-of-use\";s:14:\"help_link_text\";s:4:\"Help\";s:9:\"help_link\";s:0:\"\";s:7:\"color_1\";s:7:\"#ffffff\";s:7:\"color_2\";s:7:\"#2C333C\";s:7:\"color_3\";s:7:\"#2C333C\";s:7:\"color_4\";s:7:\"#60a1d7\";}') 
160404 9:30:25 30 Close stmt 
     21 Query ROLLBACK 
     21 Quit 
     22 Query ROLLBACK 
     22 Quit 
     23 Query ROLLBACK 
     23 Quit 
     24 Query ROLLBACK 
     24 Quit 
     25 Query ROLLBACK 
     25 Quit 
     26 Query ROLLBACK 
     26 Quit 
     27 Query ROLLBACK 
     27 Quit 
     28 Query ROLLBACK 
     28 Quit 
     29 Query ROLLBACK 
     29 Quit 
     30 Query ROLLBACK 
     30 Quit 
+0

Aktivieren Sie das Abfrageprotokoll und schauen Sie, welche Abfragen den Deadlock verursachen. Und Sie sollten das Timeout auf ein normales Niveau zurückstellen. – DanFromGermany

+0

Es ist das Einfügen in die Community-Tabelle, die fehlschlägt. Ich habe die obige Frage aktualisiert, um die Daten aus dem MySQL-Abfrageprotokoll anzuzeigen. –

+1

Während ich Ihre Frage nicht beantworte, schlage ich vor, nur zu Testzwecken zu SQLite zu wechseln. Es wird die Laufzeit Ihrer Tests drastisch beschleunigen. – Mysteryos

Antwort

2

Daher ist es nicht empfehlenswert, die Sperrwartezeit zu erhöhen; the best practice is to catch the error and recover.

Offiziell ist es das, was Sie tun sollten:

Beide Deadlocks und Sperre warten Timeouts auf ausgelasteten Servern normal sind und es notwendig ist, für Anwendungen bewusst sein, dass sie passieren kann und mit ihnen umgehen durch Wiederholen. Sie können sie weniger wahrscheinlich machen als so wenig Arbeit wie möglich zwischen der ersten Änderung der Daten während einer Transaktion und der Festschreibung, so dass die Sperren für die kürzeste möglichen Zeit und für die kleinstmögliche Anzahl von Zeilen gehalten werden . Manchmal Splitting Arbeit zwischen verschiedenen Transaktionen kann praktisch und hilfreich sein.