after_commit :update_second_level_cache, :on => :update 会导致某些问题
huacnlee opened this issue · 4 comments
不知道这个算不算问题
我们的项目里面有 RSpec 跑测试,使用 database_cleaner 来实现清除数据,清除方式是 Transaction
,然后我发现每次修改的动作 second_level_cache 都没有发起 write cache 的动作。
DatabaseCleaner.strategy = :transaction
test.log
(0.2ms) BEGIN
(0.1ms) SAVEPOINT active_record_1
(0.1ms) RELEASE SAVEPOINT active_record_1
(0.1ms) SAVEPOINT active_record_1
Photo Load (0.4ms) SELECT `photos`.* FROM `photos` WHERE `photos`.`deleted_at` IS NULL AND `photos`.`id` = 2 LIMIT 1
Cache write: slc/photo/2/3 ({:expires_in=>7 days})
Photo Exists (0.4ms) SELECT 1 AS one FROM `photos` WHERE (`photos`.`gcid` = BINARY '96b5b7b451771f9e0cf14fa72a1fceaf' AND `photos`.`id` != 2 AND `photos`.`user_id` = 2) LIMIT 1
SQL (0.3ms) UPDATE `photos` SET `title` = 'foo', `desc` = 'bar', `updated_at` = '2013-12-24 07:45:31' WHERE `photos`.`id` = 2
# 这里应该有 Cache write: slc/photo/2/3 的
Cache read: slc/photo/2/3
(0.9ms) ROLLBACK TO SAVEPOINT active_record_1
(0.1ms) ROLLBACK
我看了一下 second_level_cache 的代码,发现重写 cache 是通过 after_commit 来实现的
after_commit :update_second_level_cache, :on => :update
由于 database_cleaner 直接 Rollback 了,看起来 commit 没有被调用到。
这个文件隐藏太深了,我还一直在怀疑是我其他地方写的东西导致的问题,结果一步一步差下来才发现是这里的问题,于是我将 database_cleaner 改成 Truncation
方式,问题就没了。
DatabaseCleaner.strategy = :truncation
User Load (0.4ms) SELECT `users`.* FROM `users` WHERE `users`.`deleted_at` IS NULL AND `users`.`id` = 1 LIMIT 1
Cache write: slc/user/1/3 ({:expires_in=>7 days})
Cache read: slc/photo/1/3
(0.1ms) BEGIN
Photo Exists (0.3ms) SELECT 1 AS one FROM `photos` WHERE (`photos`.`gcid` = BINARY 'd8b61d7cd9222ccc33f6e31443be8654' AND `photos`.`id` != 1 AND `photos`.`user_id` = 1) LIMIT 1
SQL (0.2ms) UPDATE `photos` SET `title` = 'foo', `desc` = 'bar', `updated_at` = '2013-12-24 07:56:11' WHERE `photos`.`id` = 1
(1.8ms) COMMIT
Cache write: slc/photo/1/3 ({:expires_in=>7 days})
这个问题一直都存在,从缓存同步的角度,使用after commit是没问题的,确保只有写入数据库之后才同步缓存。
在 2013-12-24 下午4:01,"Jason Lee" notifications@github.com写道:
不知道这个算不算问题
我们的项目里面有 RSpec 跑测试,使用 database_cleanerhttps://github.com/bmabey/database_cleaner来实现清除数据,清除方式是
Transaction,然后我发现每次修改的动作 second_level_cache 都没有发起 write cache 的动作。DatabaseCleaner.strategy = :transaction
test.log
(0.2ms) BEGIN(0.1ms) SAVEPOINT active_record_1(0.1ms) RELEASE SAVEPOINT active_record_1(0.1ms) SAVEPOINT active_record_1
Photo Load (0.4ms) SELECT
photos
.* FROMphotos
WHEREphotos
.deleted_at
IS NULL ANDphotos
.id
= 2 LIMIT 1
Cache write: slc/photo/2/3 ({:expires_in=>7 days})
Photo Exists (0.4ms) SELECT 1 AS one FROMphotos
WHERE (photos
.gcid
= BINARY '96b5b7b451771f9e0cf14fa72a1fceaf' ANDphotos
.id
!= 2 ANDphotos
.user_id
= 2) LIMIT 1
SQL (0.3ms) UPDATEphotos
SETtitle
= 'foo',desc
= 'bar',updated_at
= '2013-12-24 07:45:31' WHEREphotos
.id
= 2# 这里应该有 Cache write: slc/photo/2/3 的
Cache read: slc/photo/2/3
(0.9ms) ROLLBACK TO SAVEPOINT active_record_1(0.1ms) ROLLBACK我看了一下 second_level_cache 的代码,发现重写 cache 是通过 after_commit 来实现的
after_commit :update_second_level_cache, :on => :update
由于 database_cleaner 直接 Rollback 了,看起来 commit 没有被调用到。
这个文件隐藏太深了,我还一直在怀疑是我其他地方写的东西导致的问题,结果一步一步差下来才发现是这里的问题,于是我将 database_cleaner
改成 Truncation 方式,问题就没了。DatabaseCleaner.strategy = :truncation
User Load (0.4ms) SELECT
users
.* FROMusers
WHEREusers
.deleted_at
IS NULL ANDusers
.id
= 1 LIMIT 1
Cache write: slc/user/1/3 ({:expires_in=>7 days})
Cache read: slc/photo/1/3(0.1ms) BEGIN
Photo Exists (0.3ms) SELECT 1 AS one FROMphotos
WHERE (photos
.gcid
= BINARY 'd8b61d7cd9222ccc33f6e31443be8654' ANDphotos
.id
!= 1 ANDphotos
.user_id
= 1) LIMIT 1
SQL (0.2ms) UPDATEphotos
SETtitle
= 'foo',desc
= 'bar',updated_at
= '2013-12-24 07:56:11' WHEREphotos
.id
= 1(1.8ms) COMMIT
Cache write: slc/photo/1/3 ({:expires_in=>7 days})—
Reply to this email directly or view it on GitHubhttps://github.com//issues/4
.
我只是觉得这个陷阱很容易遇到, DatabaseCleaner 默认的方式就是 transaction,遇到的时候很难想到是这个引起的
在readme里加个说明,怎么样?
在 2013-12-24 下午4:14,"Jason Lee" notifications@github.com写道:
我只是觉得这个陷阱很容易遇到, DatabaseCleaner 默认的方式就是 transaction,遇到的时候很难想到是这个引起的
—
Reply to this email directly or view it on GitHubhttps://github.com//issues/4#issuecomment-31162923
.
我看行!:smile: