我的一个测试类中生成了一个非常小的数据集,我尝试在setUp()方法中生成数据,但每个测试都导致锁等待超时。将此代码从setUp()方法中移出并放入自己的方法中有所帮助。这意味着并非每个测试都会抱怨锁。
我正在使用Laravel 5.2中的DatabaseTransactions特性,以便在运行每个测试用例之前重置数据库。
在我拥有的每个测试用例中,我都会调用以下代码来获取模拟数据。
$data = self::getRandomCommunityWithAssociatedData();
实际方法只会为创建的社区生成少量社区对象和用户对象。
public static function getRandomCommunityWithAssociatedData()
{
self::$communities = factory(\Community::class, self::COMMUNITIES_TO_CREATE)->create()->each(function ($community) {
self::$users[$community->id] = factory(User::class, self::USERS_TO_CREATE)->create()->each(function (\User $user) use ($community) {
$user->community()->associate($community);
});
self::$admins[$community->id] = factory(User::class, 'superadmin', self::ADMINS_TO_CREATE)->create()->each(function (\User $admin) use ($community) {
$admin->community()->associate($community);
});
});
$community = self::$communities[mt_rand(0, count(self::$communities) - 1)];
return ['community' => $community, 'users' => self::$users[$community->id], 'admins' => self::$admins[$community->id]];
}
该方法中使用了几个常量,它们用于确定要创建多少个每个对象。目前,我正在为每个社区实例创建2个社区、3个用户和2个管理员。
锁等待超时不可预测,一次运行可能发生在第一个测试用例上,另一次运行可能发生在第5个测试用例上。
我尝试将MySQL等待锁的时间增加到500秒,但仍然会出现超时情况。增加这个时间真的不是一个选项,因为测试需要能够在所有环境中运行。
使用Laravel 5.2中的DatabaseTransactions特性,为什么使用如此小的数据集时可能会出现锁等待超时的情况?有什么想法吗?
1) UserEmailNotificationsTest::testActiveAdminReceivesNewCommentEmailNotification
Illuminate\Database\QueryException: SQLSTATE[HY000]: General error: 1205 Lock wait timeout exceeded; try restarting transaction (SQL: insert into `communities` (`
上述执行的查询是在社区表上进行的简单插入操作,没有涉及任何复杂的子查询或其他数据生成操作。
启用查询日志后,结果。
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
show open tables where in_use>0;
会发生什么?如果你终止测试进程会发生什么? - cwallenpoole