我写的代码是这样的, 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 服务重启的话,数据就会更新了。
请问一下这个是什么问题,我觉得是我的代码写的有点问题,还烦请大家帮忙看看,是哪里出的问题?
2
ebony0319 2016-10-11 18:59:36 +08:00 via Android
你知道 update 不加 where 会有什么后果么? mysql 默认会阻止这种语法。
|
3
bwangel OP @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) ``` |
4
sujin190 2016-10-11 20:30:50 +08:00 1
@bwangel 你是不是插入数据先请求了次 /,然后猜更新的? return 还能执行后边的 commit 么?
没有缓存的,只是对 pymysql 的封装,有问题查 pymysql 相关的文档就行 pymysql 的 autocommit 默认是 false ,每次查询完必须手动 commit 才能查询到最新数据,你也可以修改为 true |
5
ebony0319 2016-10-11 21:47:05 +08:00 1
说两点。 mysql 有一个安全模式 SET SQL_SAFE_UPDATES = 0;可以关闭,你去查一下这个,这就是为了防止全部删除的。第二个就是楼上说的对,一定要对游标手动 commit 。
|
6
bwangel OP @sujin190 好吧,我错了,确实是, return 了肯定不能 commit 了。非常感谢您能抽空解决我的问题。
@ebony0319 ,谢谢你的回答,涨知识了。 @sujin190 ,另外,请教一下,如果我想用封装一个 get_cursor 上下文管理器,实现如下的效果,它将查询封装成一个事务,如果抛出异常了自动回滚,该如何下手呢? with get_cursor(pool) as cursor: cursor.execute(sql) 我尝试过用 contextlib.contextmanager ,但是它也会用到 yield ,然后 gen.coroutine 也会用到 yield,然后我不知道该如何处理,我就晕菜了。。 |