请教一个 TorMySQL 查询缓存的问题?

2016-10-11 17:51:22 +08:00
 bwangel

我写的代码是这样的, TorMySQL 的新手,写的有点乱,还请轻喷。

代码地址

刚开始我在表中插入了一条数据:

mysql> insert into mytable(id, value) values (1, 'cache');
Query OK, 1 row affected (0.10 sec)

然后我把服务运行起来以后,手动登陆 MySQL ,更新这个这个表:

mysql> update mytable set value = 'no';
Query OK, 1 row affected (0.06 sec)
Rows matched: 1  Changed: 1  Warnings: 0

此时,我再来请求这个/,发现返回的数据没有更新(有缓存吗?),依然是原来的值:

[{'value': 'cache', 'id': 1}]
datas is  [{'value': 'cache', 'id': 1}]
[I 161011 17:48:58 web:1971] 200 GET / (127.0.0.1) 2.33ms

如果我把 Tornado 服务重启的话,数据就会更新了。

请问一下这个是什么问题,我觉得是我的代码写的有点问题,还烦请大家帮忙看看,是哪里出的问题?

2602 次点击
所在节点    MySQL
8 条回复
bwangel
2016-10-11 17:52:47 +08:00
@sujin190

我又厚着脸皮来找你了。 Please help me 。
ebony0319
2016-10-11 18:59:36 +08:00
你知道 update 不加 where 会有什么后果么? mysql 默认会阻止这种语法。
bwangel
2016-10-11 20:04:10 +08:00
@ebony0319 ,这样写确实有问题,会默认更新所有行。

由于我当时写的测试表,只有一行,所以下意识的没有想到这一点。

另外, MySQL 会阻止这种语法吗?我看官方文档上的说明是:

The WHERE clause, if given, specifies the conditions that identify which rows to update. With no WHERE clause, all rows are updated.

所有行都会被更新啊。

另外,刚刚整了个 100499 行的表测试了一下,所有行都被更新了啊:


```
mysql> select count(*) from service;
+----------+
| count(*) |
+----------+
| 100499 |
+----------+
1 row in set (0.04 sec)

mysql> desc service;
+--------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+----------------+
| ser_id | int(11) | NO | PRI | NULL | auto_increment |
| value | varchar(32) | YES | | NULL | |
+--------+-------------+------+-----+---------+----------------+
2 rows in set (0.01 sec)

mysql> explain update service set value='abc'\G
*************************** 1. row ***************************
id: 1
select_type: UPDATE
table: service
partitions: NULL
type: index
possible_keys: NULL
key: PRIMARY
key_len: 4
ref: NULL
rows: 100827
filtered: 100.00
Extra: NULL
1 row in set (0.00 sec)

mysql> select now();update service set value='abc';select now();
+---------------------+
| now() |
+---------------------+
| 2016-10-11 20:01:18 |
+---------------------+
1 row in set (0.00 sec)

Query OK, 100499 rows affected (1.48 sec)
Rows matched: 100499 Changed: 100499 Warnings: 0

+---------------------+
| now() |
+---------------------+
| 2016-10-11 20:01:19 |
+---------------------+
1 row in set (0.00 sec)


```
sujin190
2016-10-11 20:30:50 +08:00
@bwangel 你是不是插入数据先请求了次 /,然后猜更新的? return 还能执行后边的 commit 么?
没有缓存的,只是对 pymysql 的封装,有问题查 pymysql 相关的文档就行
pymysql 的 autocommit 默认是 false ,每次查询完必须手动 commit 才能查询到最新数据,你也可以修改为 true
ebony0319
2016-10-11 21:47:05 +08:00
说两点。 mysql 有一个安全模式 SET SQL_SAFE_UPDATES = 0;可以关闭,你去查一下这个,这就是为了防止全部删除的。第二个就是楼上说的对,一定要对游标手动 commit 。
bwangel
2016-10-11 22:15:22 +08:00
@sujin190 好吧,我错了,确实是, return 了肯定不能 commit 了。非常感谢您能抽空解决我的问题。

@ebony0319 ,谢谢你的回答,涨知识了。

@sujin190 ,另外,请教一下,如果我想用封装一个 get_cursor 上下文管理器,实现如下的效果,它将查询封装成一个事务,如果抛出异常了自动回滚,该如何下手呢?

with get_cursor(pool) as cursor:
cursor.execute(sql)

我尝试过用 contextlib.contextmanager ,但是它也会用到 yield ,然后 gen.coroutine 也会用到 yield,然后我不知道该如何处理,我就晕菜了。。
sujin190
2016-10-11 22:24:51 +08:00
@bwangel python2 的话似乎不行,这也是我 with pool.Connection()不能提供 commit 事务的原因, python3 的话 with 有异步语法支持,你可以看下 python3 的异步语法,应该是可以实现的,一直想着使用 python3 的异步语法做一些改进也没时间做。。
bwangel
2016-10-11 22:53:45 +08:00
@sujin190 ,恩,好的,谢谢!

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/311982

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX