ar_cache 1.2.0 → 2.1.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: a01b3342ccad3bf06ce4438f714f00ffc467efc32f58809ab940163ebaf440d7
4
- data.tar.gz: 453c9232cbc03dee8572b1133972f01d6dd1c2501df0c9279a32a5e4243ebeb0
3
+ metadata.gz: 2d9f5ff76912fe1e2276c795f619cf2e1e88780e7592e7fcb659e55a75bd8aff
4
+ data.tar.gz: 51ccc09d008c7d345dc9901c2898463ef5d2ebd40649b829b63ba801b13948da
5
5
  SHA512:
6
- metadata.gz: 7d6a3bb90d4ac0eb3384650fd17fbed43be74da2ca0a57b55c9d19b9c68722b2d23785fd42e00cbdec8a4563cc10c6c44ac7609a8b4a09d9b4a813f47c3f2ae1
7
- data.tar.gz: 2105bf0e6e89c3d438f30b43bef1dd64b66b511968fec5c393068043ddb52ee833762f0508a4a84d25940ddac36c686c8b5fd4e6ef73d75802de878645ac265b
6
+ metadata.gz: f8422672824015d7496620282919ff08b380066c8e05d8bde53bd8ef732f6b3a1c475f86bdd258f188be151fd78734b79bddbfa00bb20ce9b78be4443e96a168
7
+ data.tar.gz: 3059b104bf49417391e3edb84c5005822ba652b8c29bf8fd0de7c23080444fbd8345da5776a8bd0ba81b515845e567776c22b0a925c0235042c7383f4610cbc6
data/CHANGELOG.md CHANGED
@@ -2,20 +2,8 @@
2
2
 
3
3
  ## main
4
4
 
5
- ## 1.2.0 (2021-03-12)
5
+ ## 2.1.0 (2018-06-29 UTC)
6
6
 
7
- [Commit [#c830907](https://github.com/OuYangJinTing/ar_cache/commit/c830907595b7d1d46a2f29204ee6051ecc3ff30c)]:
8
-
9
- - Remove methods: `ArCache::MockTable#enabled?`, `ArCache::MockTable#select_enabled?`, `ArCache::Table.enabled?`, `ArCache::Table.select_enabled?`, `ActiveRecord::Relation#skip_ar_cache`.
10
- - Rename methods: `ArCache#skip_cache? => ArCache#skip?`, `ArCache#skip_cache => ArCache#skip`, `ArCache#pre_expire? => ArCache#expire?`, `ArCache#pre_expire => ArCache#expire`.
11
- - Now, `ArCache#skip` method only skip read cache, but still try delete cache.
12
-
13
- ## 1.1.0 (2021-03-11)
14
-
15
- - [Commit [#92965d2](https://github.com/OuYangJinTing/ar_cache/commit/92965d26e130da9a13bd52ea31f3f668851f6f12)] Fully automatic delete cache when call delete_all/update_all method.
16
- - [Commit [#231cfd3](https://github.com/OuYangJinTing/ar_cache/commit/231cfd35c2c197bf41628f4f914ba39fb8debd81)] Optimize has_one(through:) cache implementation.
17
- - [Commit [#ce5444c](https://github.com/OuYangJinTing/ar_cache/commit/ce5444c8c4ec0a61bec5e07d694295d3cc5decf8)] ActiveRecord::Relation#reload and ActiveRecord::Associations::Association#reload should skip read cache if associated target is already loaded.
18
-
19
- ## 1.0.0 (2021-03-02)
20
-
21
- - Initial version.
7
+ - [PR [#4](https://github.com/OuYangJinTing/ar_cache/pull/4)] Fix high concurrency causes write dirty cache ([@OuYangJinTing](https://github.com/OuYangJinTing))
8
+ - [PR [#3](https://github.com/OuYangJinTing/ar_cache/pull/3)] Shouldn't open database transaction when use cache lock ([@OuYangJinTing](https://github.com/OuYangJinTing))
9
+ - [PR [#2](https://github.com/OuYangJinTing/ar_cache/pull/2)] Use configuration template as default values ([@OuYangJinTing](https://github.com/OuYangJinTing))
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.2.0)
4
+ ar_cache (2.1.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.1)
11
- actionpack (= 6.1.1)
12
- activesupport (= 6.1.1)
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.1)
16
- actionpack (= 6.1.1)
17
- activejob (= 6.1.1)
18
- activerecord (= 6.1.1)
19
- activestorage (= 6.1.1)
20
- activesupport (= 6.1.1)
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.1)
23
- actionpack (= 6.1.1)
24
- actionview (= 6.1.1)
25
- activejob (= 6.1.1)
26
- activesupport (= 6.1.1)
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.1)
30
- actionview (= 6.1.1)
31
- activesupport (= 6.1.1)
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.1)
37
- actionpack (= 6.1.1)
38
- activerecord (= 6.1.1)
39
- activestorage (= 6.1.1)
40
- activesupport (= 6.1.1)
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.1)
43
- activesupport (= 6.1.1)
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.1)
49
- activesupport (= 6.1.1)
49
+ activejob (6.1.3.2)
50
+ activesupport (= 6.1.3.2)
50
51
  globalid (>= 0.3.6)
51
- activemodel (6.1.1)
52
- activesupport (= 6.1.1)
53
- activerecord (6.1.1)
54
- activemodel (= 6.1.1)
55
- activesupport (= 6.1.1)
56
- activestorage (6.1.1)
57
- actionpack (= 6.1.1)
58
- activejob (= 6.1.1)
59
- activerecord (= 6.1.1)
60
- activesupport (= 6.1.1)
61
- marcel (~> 0.3.1)
62
- mimemagic (~> 0.3.2)
63
- activesupport (6.1.1)
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,86 +72,92 @@ GEM
71
72
  coderay (1.1.3)
72
73
  concurrent-ruby (1.1.8)
73
74
  crass (1.0.6)
74
- database_cleaner (1.8.5)
75
+ dalli (2.7.11)
76
+ database_cleaner (2.0.1)
77
+ database_cleaner-active_record (~> 2.0.0)
78
+ database_cleaner-active_record (2.0.1)
79
+ activerecord (>= 5.a)
80
+ database_cleaner-core (~> 2.0.0)
81
+ database_cleaner-core (2.0.1)
75
82
  erubi (1.10.0)
76
83
  globalid (0.4.2)
77
84
  activesupport (>= 4.2.0)
78
- i18n (1.8.7)
85
+ i18n (1.8.10)
79
86
  concurrent-ruby (~> 1.0)
80
- loofah (2.9.0)
87
+ loofah (2.9.1)
81
88
  crass (~> 1.0.2)
82
89
  nokogiri (>= 1.5.9)
83
90
  mail (2.7.1)
84
91
  mini_mime (>= 0.1.1)
85
- marcel (0.3.3)
86
- mimemagic (~> 0.3.2)
92
+ marcel (1.0.1)
87
93
  method_source (1.0.0)
88
- mimemagic (0.3.5)
89
- mini_mime (1.0.2)
90
- minitest (5.14.3)
91
- nio4r (2.5.4)
92
- nokogiri (1.11.1-x86_64-linux)
94
+ mini_mime (1.0.3)
95
+ minitest (5.14.4)
96
+ nio4r (2.5.7)
97
+ nokogiri (1.11.6-x86_64-linux)
93
98
  racc (~> 1.4)
99
+ oj (3.11.5)
94
100
  parallel (1.20.1)
95
- parser (3.0.0.0)
101
+ parser (3.0.1.1)
96
102
  ast (~> 2.4.1)
97
- pry (0.13.1)
103
+ pry (0.14.1)
98
104
  coderay (~> 1.1)
99
105
  method_source (~> 1.0)
100
106
  racc (1.5.2)
101
107
  rack (2.2.3)
102
108
  rack-test (1.1.0)
103
109
  rack (>= 1.0, < 3)
104
- rails (6.1.1)
105
- actioncable (= 6.1.1)
106
- actionmailbox (= 6.1.1)
107
- actionmailer (= 6.1.1)
108
- actionpack (= 6.1.1)
109
- actiontext (= 6.1.1)
110
- actionview (= 6.1.1)
111
- activejob (= 6.1.1)
112
- activemodel (= 6.1.1)
113
- activerecord (= 6.1.1)
114
- activestorage (= 6.1.1)
115
- activesupport (= 6.1.1)
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)
116
122
  bundler (>= 1.15.0)
117
- railties (= 6.1.1)
123
+ railties (= 6.1.3.2)
118
124
  sprockets-rails (>= 2.0.0)
119
125
  rails-dom-testing (2.0.3)
120
126
  activesupport (>= 4.2.0)
121
127
  nokogiri (>= 1.6)
122
128
  rails-html-sanitizer (1.3.0)
123
129
  loofah (~> 2.3)
124
- railties (6.1.1)
125
- actionpack (= 6.1.1)
126
- activesupport (= 6.1.1)
130
+ railties (6.1.3.2)
131
+ actionpack (= 6.1.3.2)
132
+ activesupport (= 6.1.3.2)
127
133
  method_source
128
134
  rake (>= 0.8.7)
129
135
  thor (~> 1.0)
130
136
  rainbow (3.0.0)
131
137
  rake (13.0.3)
138
+ redis (4.2.5)
132
139
  regexp_parser (2.1.1)
133
- rexml (3.2.4)
134
- rubocop (1.11.0)
140
+ rexml (3.2.5)
141
+ rubocop (1.15.0)
135
142
  parallel (~> 1.10)
136
143
  parser (>= 3.0.0.0)
137
144
  rainbow (>= 2.2.2, < 4.0)
138
145
  regexp_parser (>= 1.8, < 3.0)
139
146
  rexml
140
- rubocop-ast (>= 1.2.0, < 2.0)
147
+ rubocop-ast (>= 1.5.0, < 2.0)
141
148
  ruby-progressbar (~> 1.7)
142
149
  unicode-display_width (>= 1.4.0, < 3.0)
143
- rubocop-ast (1.4.1)
144
- parser (>= 2.7.1.5)
145
- rubocop-minitest (0.10.3)
146
- rubocop (>= 0.87, < 2.0)
147
- rubocop-performance (1.9.2)
148
- rubocop (>= 0.90.0, < 2.0)
150
+ rubocop-ast (1.6.0)
151
+ parser (>= 3.0.1.1)
152
+ rubocop-minitest (0.12.1)
153
+ rubocop (>= 0.90, < 2.0)
154
+ rubocop-performance (1.11.3)
155
+ rubocop (>= 1.7.0, < 2.0)
149
156
  rubocop-ast (>= 0.4.0)
150
- rubocop-rails (2.9.1)
157
+ rubocop-rails (2.10.1)
151
158
  activesupport (>= 4.2.0)
152
159
  rack (>= 1.1)
153
- rubocop (>= 0.90.0, < 2.0)
160
+ rubocop (>= 1.7.0, < 2.0)
154
161
  rubocop-rake (0.5.1)
155
162
  rubocop
156
163
  ruby-progressbar (1.11.0)
@@ -166,7 +173,7 @@ GEM
166
173
  tzinfo (2.0.4)
167
174
  concurrent-ruby (~> 1.0)
168
175
  unicode-display_width (2.0.0)
169
- websocket-driver (0.7.3)
176
+ websocket-driver (0.7.4)
170
177
  websocket-extensions (>= 0.1.0)
171
178
  websocket-extensions (0.1.5)
172
179
  zeitwerk (2.4.2)
@@ -176,11 +183,13 @@ PLATFORMS
176
183
 
177
184
  DEPENDENCIES
178
185
  ar_cache!
186
+ dalli
179
187
  database_cleaner
180
188
  minitest
181
189
  pry
182
190
  rails
183
191
  rake
192
+ redis
184
193
  rubocop
185
194
  rubocop-minitest
186
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
+ - ...