V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
MySQL 5.5 Community Server
MySQL 5.6 Community Server
Percona Configuration Wizard
XtraBackup 搭建主从复制
Great Sites on MySQL
Percona
MySQL Performance Blog
Severalnines
推荐管理工具
Sequel Pro
phpMyAdmin
推荐书目
MySQL Cookbook
MySQL 相关项目
MariaDB
Drizzle
参考文档
http://mysql-python.sourceforge.net/MySQLdb.html
bwangel
V2EX  ›  MySQL

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

  •  
  •   bwangel ·
    bwangelme · 2016-10-11 17:51:22 +08:00 · 2522 次点击
    这是一个创建于 2760 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我写的代码是这样的, 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 服务重启的话,数据就会更新了。

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

    8 条回复    2016-10-11 22:53:45 +08:00
    bwangel
        1
    bwangel  
    OP
       2016-10-11 17:52:47 +08:00
    @sujin190

    我又厚着脸皮来找你了。 Please help me 。
    ebony0319
        2
    ebony0319  
       2016-10-11 18:59:36 +08:00 via Android
    你知道 update 不加 where 会有什么后果么? mysql 默认会阻止这种语法。
    bwangel
        3
    bwangel  
    OP
       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
        4
    sujin190  
       2016-10-11 20:30:50 +08:00   ❤️ 1
    @bwangel 你是不是插入数据先请求了次 /,然后猜更新的? return 还能执行后边的 commit 么?
    没有缓存的,只是对 pymysql 的封装,有问题查 pymysql 相关的文档就行
    pymysql 的 autocommit 默认是 false ,每次查询完必须手动 commit 才能查询到最新数据,你也可以修改为 true
    ebony0319
        5
    ebony0319  
       2016-10-11 21:47:05 +08:00   ❤️ 1
    说两点。 mysql 有一个安全模式 SET SQL_SAFE_UPDATES = 0;可以关闭,你去查一下这个,这就是为了防止全部删除的。第二个就是楼上说的对,一定要对游标手动 commit 。
    bwangel
        6
    bwangel  
    OP
       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
        7
    sujin190  
       2016-10-11 22:24:51 +08:00
    @bwangel python2 的话似乎不行,这也是我 with pool.Connection()不能提供 commit 事务的原因, python3 的话 with 有异步语法支持,你可以看下 python3 的异步语法,应该是可以实现的,一直想着使用 python3 的异步语法做一些改进也没时间做。。
    bwangel
        8
    bwangel  
    OP
       2016-10-11 22:53:45 +08:00
    @sujin190 ,恩,好的,谢谢!
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   960 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 18:35 · PVG 02:35 · LAX 11:35 · JFK 14:35
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.