ar_cache 1.5.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 86d921c69c8ac7d8cbc0cefdb5614120a60f5663c5a2b8e3bc07a1c9c1d8d8a0
4
- data.tar.gz: ced6d5cf673fb6e83070ba95e4daf6fb9d0994a93f8963de63692317c9c77081
3
+ metadata.gz: d4d25cbd1abb845a90dbd29d50d1dfb5b622e454e6c0bfe4a1ae65b4eddb818f
4
+ data.tar.gz: 821f3036d2df0db1f143a3212cffacf306ac30aa2335385defde6b41edf5f46d
5
5
  SHA512:
6
- metadata.gz: 5affbd42eed0837bc8fc40fd317eac39fa79b0e18c8e27f65eefb2873b381064539374dde7b963c1993f66068177707e72421499d7ff81b5fdc394e91261f8c3
7
- data.tar.gz: 1c7f9930f0a726201afa735d208c229c01693432adc1631ea5bcd6417210ad079587c18ac9e908890e4ae4fac2307361048f017a28308c92c22d9136dd36e5ce
6
+ metadata.gz: a0a9706501fa606ee7cf02931bdbfc5efd3e2668fb5b51c55b971d616233b43595363b30ccf279d500df64789268398c140870c8683b7e79e8b70717ebd2983a
7
+ data.tar.gz: 46e0a6c9a76401dec6d2f3c11f52e4e9a3e0d1b975c827df7eca05f0068612d78755238db00c5f170ab30523c5aee15eb6556b3956599490d0a812d4f8d917d5
data/CHANGELOG.md CHANGED
@@ -1,44 +1,3 @@
1
1
  # Change log
2
2
 
3
3
  ## main
4
-
5
- ## 1.5.0 (2021-03-22 UTC)
6
-
7
- [Compare [#7cc9ec8..10f9eea](https://github.com/OuYangJinTing/ar_cache/compare/7cc9ec8..10f9eea)]:
8
-
9
- - Fix `has_one thtough:` strict loading error.
10
- - Fix `#detect_wrong_key`, should check `nil` value match.
11
- - Rename `ArCache::Configuration#index_column_max_size` => `ArCache::Configuration#column_length`
12
-
13
- ## 1.4.0 (2021-03-15 UTC)
14
-
15
- [Compare [#3ff0bb8..7cc9ec8](https://github.com/OuYangJinTing/ar_cache/compare/3ff0bb8..7cc9ec8)]:
16
-
17
- - Remove `ArCache::Table` `ignored_columns` configuration.
18
- - Fix `ActiveRecord` call `#select` write to cache data is incomplete.
19
-
20
- ## 1.3.0 (2021-03-13 UTC)
21
-
22
- [Compare [#4328f38..4ec14e9](https://github.com/OuYangJinTing/ar_cache/compare/4328f38..4ec14e9)]:
23
-
24
- - Optimize association cache, only cacheable association use ArCache query now.
25
-
26
- ## 1.2.0 (2021-03-12 UTC)
27
-
28
- [Compare [#eb27f99..c830907](https://github.com/OuYangJinTing/ar_cache/compare/eb27f99..c830907)]:
29
-
30
- - Remove methods: `ArCache::MockTable#enabled?`, `ArCache::MockTable#select_enabled?`, `ArCache::Table.enabled?`, `ArCache::Table.select_enabled?`, `ActiveRecord::Relation#skip_ar_cache`.
31
- - Rename methods: `ArCache#skip_cache? => ArCache#skip?`, `ArCache#skip_cache => ArCache#skip`, `ArCache#pre_expire? => ArCache#expire?`, `ArCache#pre_expire => ArCache#expire`.
32
- - Now, `ArCache#skip` method only skip read cache, but still try delete cache.
33
-
34
- ## 1.1.0 (2021-03-10 UTC)
35
-
36
- [Compare [#a15d5f5..ce5444c](https://github.com/OuYangJinTing/ar_cache/compare/a15d5f5...ce5444c)]:
37
-
38
- - Fully automatic delete cache when call delete_all/update_all method.
39
- - Optimize has_one(through:) cache implementation.
40
- - ActiveRecord::Relation#reload and ActiveRecord::Associations::Association#reload should skip read cache if associated target is already loaded.
41
-
42
- ## 1.0.0 (2021-03-02 UTC)
43
-
44
- - Initial version.
data/Gemfile.common CHANGED
@@ -5,6 +5,8 @@ gemspec
5
5
 
6
6
  gem 'rake'
7
7
 
8
+ gem 'redis'
9
+ gem 'dalli'
8
10
  gem 'sqlite3'
9
11
  gem 'database_cleaner'
10
12
 
data/Gemfile.lock CHANGED
@@ -1,66 +1,67 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ar_cache (1.5.0)
4
+ ar_cache (2.0.0)
5
5
  activerecord (>= 6.1, < 7)
6
+ oj (>= 3, < 4)
6
7
 
7
8
  GEM
8
9
  remote: https://rubygems.org/
9
10
  specs:
10
- actioncable (6.1.3)
11
- actionpack (= 6.1.3)
12
- activesupport (= 6.1.3)
11
+ actioncable (6.1.3.2)
12
+ actionpack (= 6.1.3.2)
13
+ activesupport (= 6.1.3.2)
13
14
  nio4r (~> 2.0)
14
15
  websocket-driver (>= 0.6.1)
15
- actionmailbox (6.1.3)
16
- actionpack (= 6.1.3)
17
- activejob (= 6.1.3)
18
- activerecord (= 6.1.3)
19
- activestorage (= 6.1.3)
20
- activesupport (= 6.1.3)
16
+ actionmailbox (6.1.3.2)
17
+ actionpack (= 6.1.3.2)
18
+ activejob (= 6.1.3.2)
19
+ activerecord (= 6.1.3.2)
20
+ activestorage (= 6.1.3.2)
21
+ activesupport (= 6.1.3.2)
21
22
  mail (>= 2.7.1)
22
- actionmailer (6.1.3)
23
- actionpack (= 6.1.3)
24
- actionview (= 6.1.3)
25
- activejob (= 6.1.3)
26
- activesupport (= 6.1.3)
23
+ actionmailer (6.1.3.2)
24
+ actionpack (= 6.1.3.2)
25
+ actionview (= 6.1.3.2)
26
+ activejob (= 6.1.3.2)
27
+ activesupport (= 6.1.3.2)
27
28
  mail (~> 2.5, >= 2.5.4)
28
29
  rails-dom-testing (~> 2.0)
29
- actionpack (6.1.3)
30
- actionview (= 6.1.3)
31
- activesupport (= 6.1.3)
30
+ actionpack (6.1.3.2)
31
+ actionview (= 6.1.3.2)
32
+ activesupport (= 6.1.3.2)
32
33
  rack (~> 2.0, >= 2.0.9)
33
34
  rack-test (>= 0.6.3)
34
35
  rails-dom-testing (~> 2.0)
35
36
  rails-html-sanitizer (~> 1.0, >= 1.2.0)
36
- actiontext (6.1.3)
37
- actionpack (= 6.1.3)
38
- activerecord (= 6.1.3)
39
- activestorage (= 6.1.3)
40
- activesupport (= 6.1.3)
37
+ actiontext (6.1.3.2)
38
+ actionpack (= 6.1.3.2)
39
+ activerecord (= 6.1.3.2)
40
+ activestorage (= 6.1.3.2)
41
+ activesupport (= 6.1.3.2)
41
42
  nokogiri (>= 1.8.5)
42
- actionview (6.1.3)
43
- activesupport (= 6.1.3)
43
+ actionview (6.1.3.2)
44
+ activesupport (= 6.1.3.2)
44
45
  builder (~> 3.1)
45
46
  erubi (~> 1.4)
46
47
  rails-dom-testing (~> 2.0)
47
48
  rails-html-sanitizer (~> 1.1, >= 1.2.0)
48
- activejob (6.1.3)
49
- activesupport (= 6.1.3)
49
+ activejob (6.1.3.2)
50
+ activesupport (= 6.1.3.2)
50
51
  globalid (>= 0.3.6)
51
- activemodel (6.1.3)
52
- activesupport (= 6.1.3)
53
- activerecord (6.1.3)
54
- activemodel (= 6.1.3)
55
- activesupport (= 6.1.3)
56
- activestorage (6.1.3)
57
- actionpack (= 6.1.3)
58
- activejob (= 6.1.3)
59
- activerecord (= 6.1.3)
60
- activesupport (= 6.1.3)
61
- marcel (~> 0.3.1)
62
- mimemagic (~> 0.3.2)
63
- activesupport (6.1.3)
52
+ activemodel (6.1.3.2)
53
+ activesupport (= 6.1.3.2)
54
+ activerecord (6.1.3.2)
55
+ activemodel (= 6.1.3.2)
56
+ activesupport (= 6.1.3.2)
57
+ activestorage (6.1.3.2)
58
+ actionpack (= 6.1.3.2)
59
+ activejob (= 6.1.3.2)
60
+ activerecord (= 6.1.3.2)
61
+ activesupport (= 6.1.3.2)
62
+ marcel (~> 1.0.0)
63
+ mini_mime (~> 1.0.2)
64
+ activesupport (6.1.3.2)
64
65
  concurrent-ruby (~> 1.0, >= 1.0.2)
65
66
  i18n (>= 1.6, < 2)
66
67
  minitest (>= 5.1)
@@ -71,91 +72,92 @@ GEM
71
72
  coderay (1.1.3)
72
73
  concurrent-ruby (1.1.8)
73
74
  crass (1.0.6)
75
+ dalli (2.7.11)
74
76
  database_cleaner (2.0.1)
75
77
  database_cleaner-active_record (~> 2.0.0)
76
- database_cleaner-active_record (2.0.0)
78
+ database_cleaner-active_record (2.0.1)
77
79
  activerecord (>= 5.a)
78
80
  database_cleaner-core (~> 2.0.0)
79
81
  database_cleaner-core (2.0.1)
80
82
  erubi (1.10.0)
81
83
  globalid (0.4.2)
82
84
  activesupport (>= 4.2.0)
83
- i18n (1.8.9)
85
+ i18n (1.8.10)
84
86
  concurrent-ruby (~> 1.0)
85
- loofah (2.9.0)
87
+ loofah (2.9.1)
86
88
  crass (~> 1.0.2)
87
89
  nokogiri (>= 1.5.9)
88
90
  mail (2.7.1)
89
91
  mini_mime (>= 0.1.1)
90
- marcel (0.3.3)
91
- mimemagic (~> 0.3.2)
92
+ marcel (1.0.1)
92
93
  method_source (1.0.0)
93
- mimemagic (0.3.5)
94
- mini_mime (1.0.2)
94
+ mini_mime (1.0.3)
95
95
  minitest (5.14.4)
96
96
  nio4r (2.5.7)
97
- nokogiri (1.11.2-x86_64-linux)
97
+ nokogiri (1.11.6-x86_64-linux)
98
98
  racc (~> 1.4)
99
+ oj (3.11.5)
99
100
  parallel (1.20.1)
100
- parser (3.0.0.0)
101
+ parser (3.0.1.1)
101
102
  ast (~> 2.4.1)
102
- pry (0.14.0)
103
+ pry (0.14.1)
103
104
  coderay (~> 1.1)
104
105
  method_source (~> 1.0)
105
106
  racc (1.5.2)
106
107
  rack (2.2.3)
107
108
  rack-test (1.1.0)
108
109
  rack (>= 1.0, < 3)
109
- rails (6.1.3)
110
- actioncable (= 6.1.3)
111
- actionmailbox (= 6.1.3)
112
- actionmailer (= 6.1.3)
113
- actionpack (= 6.1.3)
114
- actiontext (= 6.1.3)
115
- actionview (= 6.1.3)
116
- activejob (= 6.1.3)
117
- activemodel (= 6.1.3)
118
- activerecord (= 6.1.3)
119
- activestorage (= 6.1.3)
120
- activesupport (= 6.1.3)
110
+ rails (6.1.3.2)
111
+ actioncable (= 6.1.3.2)
112
+ actionmailbox (= 6.1.3.2)
113
+ actionmailer (= 6.1.3.2)
114
+ actionpack (= 6.1.3.2)
115
+ actiontext (= 6.1.3.2)
116
+ actionview (= 6.1.3.2)
117
+ activejob (= 6.1.3.2)
118
+ activemodel (= 6.1.3.2)
119
+ activerecord (= 6.1.3.2)
120
+ activestorage (= 6.1.3.2)
121
+ activesupport (= 6.1.3.2)
121
122
  bundler (>= 1.15.0)
122
- railties (= 6.1.3)
123
+ railties (= 6.1.3.2)
123
124
  sprockets-rails (>= 2.0.0)
124
125
  rails-dom-testing (2.0.3)
125
126
  activesupport (>= 4.2.0)
126
127
  nokogiri (>= 1.6)
127
128
  rails-html-sanitizer (1.3.0)
128
129
  loofah (~> 2.3)
129
- railties (6.1.3)
130
- actionpack (= 6.1.3)
131
- activesupport (= 6.1.3)
130
+ railties (6.1.3.2)
131
+ actionpack (= 6.1.3.2)
132
+ activesupport (= 6.1.3.2)
132
133
  method_source
133
134
  rake (>= 0.8.7)
134
135
  thor (~> 1.0)
135
136
  rainbow (3.0.0)
136
137
  rake (13.0.3)
138
+ redis (4.2.5)
137
139
  regexp_parser (2.1.1)
138
- rexml (3.2.4)
139
- rubocop (1.11.0)
140
+ rexml (3.2.5)
141
+ rubocop (1.15.0)
140
142
  parallel (~> 1.10)
141
143
  parser (>= 3.0.0.0)
142
144
  rainbow (>= 2.2.2, < 4.0)
143
145
  regexp_parser (>= 1.8, < 3.0)
144
146
  rexml
145
- rubocop-ast (>= 1.2.0, < 2.0)
147
+ rubocop-ast (>= 1.5.0, < 2.0)
146
148
  ruby-progressbar (~> 1.7)
147
149
  unicode-display_width (>= 1.4.0, < 3.0)
148
- rubocop-ast (1.4.1)
149
- parser (>= 2.7.1.5)
150
- rubocop-minitest (0.11.0)
150
+ rubocop-ast (1.6.0)
151
+ parser (>= 3.0.1.1)
152
+ rubocop-minitest (0.12.1)
151
153
  rubocop (>= 0.90, < 2.0)
152
- rubocop-performance (1.10.1)
153
- rubocop (>= 0.90.0, < 2.0)
154
+ rubocop-performance (1.11.3)
155
+ rubocop (>= 1.7.0, < 2.0)
154
156
  rubocop-ast (>= 0.4.0)
155
- rubocop-rails (2.9.1)
157
+ rubocop-rails (2.10.1)
156
158
  activesupport (>= 4.2.0)
157
159
  rack (>= 1.1)
158
- rubocop (>= 0.90.0, < 2.0)
160
+ rubocop (>= 1.7.0, < 2.0)
159
161
  rubocop-rake (0.5.1)
160
162
  rubocop
161
163
  ruby-progressbar (1.11.0)
@@ -171,7 +173,7 @@ GEM
171
173
  tzinfo (2.0.4)
172
174
  concurrent-ruby (~> 1.0)
173
175
  unicode-display_width (2.0.0)
174
- websocket-driver (0.7.3)
176
+ websocket-driver (0.7.4)
175
177
  websocket-extensions (>= 0.1.0)
176
178
  websocket-extensions (0.1.5)
177
179
  zeitwerk (2.4.2)
@@ -181,11 +183,13 @@ PLATFORMS
181
183
 
182
184
  DEPENDENCIES
183
185
  ar_cache!
186
+ dalli
184
187
  database_cleaner
185
188
  minitest
186
189
  pry
187
190
  rails
188
191
  rake
192
+ redis
189
193
  rubocop
190
194
  rubocop-minitest
191
195
  rubocop-performance
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # ArCache
1
+ # ArCache (This is outdated, please see [中文文档](README.zh-CN.md))
2
2
 
3
3
  ![Test Status](https://github.com/OuYangJinTing/ar_cache/workflows/CI/badge.svg)
4
4
  [![Gem Version](https://badge.fury.io/rb/ar_cache.svg)](https://badge.fury.io/rb/ar_cache)
@@ -16,7 +16,7 @@ then query the database and write the result to the cache.
16
16
  - `Read cache`: Automatically intercept ActiveRecord queries, then try to fetch data from cache.
17
17
  - `Write cache`: If the query is cacheable and the cached data is not exists, it will be automatically written to the cache after the query.
18
18
  - `Expire cache`: Automatically expire cache after updated/modified data.
19
- - `Iterative cache`: The cache version will be updated after table fields, `ArCache` switch or `ArCache` coder changed.
19
+ - `Iterative cache`: The cache version will be updated after table fields or `ArCache` switch changed.
20
20
  - `Shared cache`: The cache is not only used with ActiveRecord, you can easily use it in other places.([see examples](examples))
21
21
 
22
22
  ## Installation
@@ -55,11 +55,11 @@ rake db:migrate
55
55
 
56
56
  Skip cache:
57
57
 
58
- - `ArCache#skip`, eg:
58
+ - `ArCache#skip_cache`, eg:
59
59
 
60
60
  ```ruby
61
61
  # All queries in the block will not use the cache.
62
- ArCache.skip { User.find(1) }
62
+ ArCache.skip_cache { User.find(1) }
63
63
  ```
64
64
 
65
65
  - `ActiveRecord::Persistence#reload`, eg:
data/README.zh-CN.md ADDED
@@ -0,0 +1,165 @@
1
+ # ArCache
2
+
3
+ ![Test Status](https://github.com/OuYangJinTing/ar_cache/workflows/CI/badge.svg)
4
+ [![Gem Version](https://badge.fury.io/rb/ar_cache.svg)](https://badge.fury.io/rb/ar_cache)
5
+
6
+ `ArCache` 是一个现代的 `ActiveRecord` 查询缓存库,它受 [`cache-money`](https://github.com/ngmoco/cache-money) 和 [`second_level_cache`](https://github.com/hooopo/second_level_cache) 的启发而创作。
7
+ 当 `ActiveRecord` 实例化查询条件命中唯一索引时,`ArCache` 会拦截此次查询,尝试从缓存中获取结果;如果缓存缺失,
8
+ 将在 `ActiveRecord` 查询完成后自动填充缓存。
9
+ `ArCache` 会自动维护缓存的正确性。
10
+
11
+ ## 特点
12
+
13
+ - **低影响**:如果项目里数据库操作的相关代码符合 `ActiveRecord` 风格的话,那么你可以直接引入 `ArCache`,无需修改任何代码。([详细](#警告))
14
+ - **读缓存**:当实例化查询的条件命中唯一索引时,`ArCache` 会尝试从缓存中获取结果返回。
15
+ - **写缓存**:当读缓存操作没有获取到结果时,`ArCache` 会在 `ActiveRecord` 查询操作结束后,写入缓存。
16
+ - **删缓存**:在更新或删除数据后,`ArCache` 会自动移除对应的缓存。
17
+ - **迭代缓存**:当表结构发生改变后,`ArCache` 会更新这个表对应的缓存版本。
18
+ - **共享缓存**:`ArCache` 里面缓存是完整表字段与数据的哈希结果的 `json` 序列化字符串(仅当使用 `redis/memcached` 作为存储器时),因此缓存的使用是没有局限的。([实例](examples))
19
+
20
+ ## 安装
21
+
22
+ 向项目的 `Gemfile` 文件里增加一行内容:
23
+
24
+ ```ruby
25
+ gem 'ar_cache'
26
+ ```
27
+
28
+ 之后,执行:
29
+
30
+ ```shell
31
+ bundle install
32
+ ```
33
+
34
+ ## 初始化配置文件
35
+
36
+ 如果是 `rails` 项目,直接执行命令:
37
+
38
+ ```shell
39
+ rails generate ar_cache:install
40
+ ```
41
+
42
+ 不是,则将 [configuration.rb](lib/generators/ar_cache/templates/configuration.rb) 文件手动复制到项目对应的目录。
43
+
44
+ ## 配置项
45
+
46
+ 关于配置项的说明,请直接查看 [configuration.rb](lib/generators/ar_cache/templates/configuration.rb) 文件.
47
+
48
+ ## 用法
49
+
50
+ 只需要了解如何删除缓存和跳过缓存即可。
51
+
52
+ 删除缓存:
53
+
54
+ - `ArCache::Table#delete`, 例如:
55
+
56
+ ```ruby
57
+ User.ar_cache_table.delete(id...)
58
+ User.first.ar_cache_table.delete(id...)
59
+ ```
60
+
61
+ 跳过缓存:
62
+
63
+ - `ArCache#skip_cache`, 例如:
64
+
65
+ ```ruby
66
+ ArCache.skip_cache do
67
+ # 块里面的全部查询将跳过缓存
68
+ end
69
+ ```
70
+
71
+ - `ActiveRecord::Persistence#reload`, 例如:
72
+
73
+ ```ruby
74
+ User.find(1).reload
75
+ ```
76
+
77
+ - `ActiveRecord::Relation#reload`, 例如:
78
+
79
+ ```ruby
80
+ # 当 relation 已加载查询后,再调用 reload 方法时,将跳过缓存
81
+ User.where(id: 1).load.reload
82
+ ```
83
+
84
+ - `ActiveRecord::Associations::Association#reload`, 例如:
85
+
86
+ ```ruby
87
+ # 当关联对象已加载查询后,再调用 reload 方法时,将跳过缓存
88
+ user.association(:account).load_target.reload
89
+ ```
90
+
91
+ ## 可读缓存的查询
92
+
93
+ 必须满足下列全部条件:
94
+
95
+ - 使用哈希作为查询条件
96
+ - 查询条件包含唯一索引
97
+ - 没有事务存在,或者事务里面没有查询表的更新或删除操作(后续会尝试解除这个限制)
98
+ - 没有调用过 `select` 方法,或者 `select` 字段都是表字段
99
+ - 没有调用过 `order/order!` 方法,或者 `order` 字段只有一个,并且该字段是表字段
100
+ - 没有调用过 `limit/limit!` 方法,或者查询条件只能命中一个结果
101
+ - 没有调用过 `skip_query_cache!` 方法
102
+ - 没有调用过 `lock/lock!` 方法
103
+ - 没有调用过 `distinct/distinct!` 方法
104
+ - 没有调用过 `group/group!` 方法
105
+ - 没有调用过 `joins/joins!` 方法
106
+ - 没有调用过 `left_outer_joins/left_outer_joins!` 方法
107
+ - 没有调用过 `offset/offset!` 方法
108
+ - 没有调用过 `eager_load/eager_load!` 方法
109
+ - 没有调用过 `references/references!` 方法
110
+ - 没有调用过 `from/from!` 方法
111
+ - ...
112
+
113
+ ```ruby
114
+ User.find(1) # 主键查询是可读缓存的
115
+ User.where(email: 'foobar@gmail.com') # 唯一索引查询是可读缓存的
116
+ User.where(id: [1, 2]) # 唯一索引有多个值的情况,依然是可读缓存的
117
+ User.where(name: 'foobar', status: :active) # 联合字段的唯一索引查询是可读缓存的
118
+ User.includes(:account).where(id: [1, 2]) # ActiveRecord 的预加载是可读缓存的(仅当为 has_one 关联时)
119
+ User.first.account # ActiveRecord 的关联对象是可读缓存的(仅当为 has_one 关联时)
120
+ ```
121
+
122
+ 注意: `has_many` 的关联缓存,目前是不支持的,后续会尝试支持,但希望不大。
123
+
124
+ ## 缓存迭代
125
+
126
+ `ArCache` 的缓存是以表为层级的,当触发缓存迭代后,这个表的全部缓存都会失效,导致一种类似缓存雪崩的情况,请特别注意。
127
+ 下述的这些情况会导致缓存迭代:
128
+
129
+ - 表结构发生变化
130
+ - 激活/禁用 `ArCache`
131
+ - 使用 `ActiveRecord::Persistence::ClassMethods#upsert_all` 方法
132
+
133
+ ## 注意事项
134
+
135
+ - `ArCache` 的缓存清除操作,是在事务提交或 `sql` 操作结束后开始的,这意味是可能出现脏读的(后续会尝试解决)。
136
+ - `ArCache` 缓存数据是完整的表行数据,因此当 `sql` 包含 `select` 字段,并且缓存缺失时,`ArCache` 会将其改成 `select *`,但最终实例化的对象依旧符合预期。
137
+ - 当使用跳过 `ActiveReord` 的回调方法,更新/删除数据时,`ArCache` 可能会多执行一条 `select primary_key` 的 `sql`,因为清除缓存需要 `primary_key` 数据。
138
+
139
+ ## 警告
140
+
141
+ 下述的这些情况都是严禁发生的行为,这些行为会导致 `ArCache` 的缓存正确性。
142
+ PS:`ActiveRecord` 使用者,不应该写出这些代码。
143
+
144
+ - 直接使用 `execute` 方法 更新/删除 数据。
145
+ - 直接使用比 `execute` 更底层方式,更新/删除 数据。
146
+ - 跳过 `ActiveRecord` 直接 更新/删除 数据。(后续会提供数据库触发器来解除这个限制)
147
+
148
+ 如果这些行为无法避免的话,请按照上述[删除缓存](#用法)的方法,手动删除受影响的缓存数据,或者干脆直接禁止对应表的 `ArCache` 功能。
149
+
150
+ ## 其它类似的库
151
+
152
+ 这里还有一些其它的 `gem`,也提供了 `ActiveRecord` 的查询缓存功能。
153
+
154
+ - [identity_cache](https://github.com/Shopify/identity_cache)
155
+ - [second_level_cache](https://github.com/hooopo/second_level_cache)
156
+ - [cache-money](https://github.com/ngmoco/cache-money)
157
+
158
+ `ArCache` 跟他们存在一些下述的差异:
159
+
160
+ - `ArCache` 不依赖 `ActiveRecord` 的 `commit` 回调,所以你可以无所顾虑的直接使用跳过回调的方法。
161
+ - `ArCache` 的缓存是 `json` 序列化,不是 `Marshal` 序列化,所以缓存的使用是没有局限的。(仅当使用 `redis/memcached` 作为存储器时)
162
+ - `ArCache` 自动代理了标准的 `ActiveRecord` 实例化查询请求,所以不需要额外学习怎么使用缓存。
163
+ - `ArCache` 缓存是懒写入的,因此新创建的数据,不会直接写入缓存。
164
+ - `ArCache` 不会热更新缓存,因此数据被更新后,缓存就没有了。
165
+ - ...