首页 存档 技术 查看内容

记一次使用MySQLdb事务时,select出现的bug 记一次使用 MySQLdb 事务时,select 出现 ...

2018-3-30 13:00 |来自: 互联网 333 0

摘要: 记一次使用 MySQLdb 事务时,select 出现的 bug 场景还原 为了能够清楚的描述这个问题,我们写一个简单的服务,语言使用 python,框架使用 tornado,数据库使用 mysql,数据库连接使用 MySQLdb。 在数据库里有这样 ...

记一次使用 MySQLdb 事务时,select 出现的 bug

场景还原


为了能够清楚的描述这个问题,我们写一个简单的服务,语言使用 python,框架使用 tornado,数据库使用 mysql,数据库连接使用 MySQLdb。


在数据库里有这样一张表:

1
2
3
4
5
drop table if exists singers;
CREATE TABLE singers(
id int PRIMARY KEY AUTO_INCREMENT,
name char(20) NOT NULL
);


而我们的服务器代码也是很简单的, 根本没什么服务可言,就是收到访问,就读取 id 为 1 的歌手姓名,并打印:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import MySQLdb
import tornado.ioloop
import tornado.web

host = '127.0.0.1'
user = 'root'
passwd = '627'
port = 3306
db = 'test'

conn = MySQLdb.connect(host=host, user=user, passwd=passwd, port=port, db=db)

class MainHandler(tornado.web.RequestHandler):
def get(self):
cur = conn.cursor()
cur.EⅩEcute("select name from singers Where `id` = 1")
res = cur.fetchone()
print res
self.write("ok")

application = tornado.web.Application([
(r"/", MainHandler),
])

if __name__ == "__main__":
application.listen(8888)
tornado.ioloop.IOLoop.instance().start()


并且我们的数据库中会有这样一条记录:

 ---- ------------ 
| id | name | ---- ------------
| 1 | jay | ---- ------------


在 shell 请求此服务和打印的结果:

curl http://localhost:8888
(jay,)


现在我们保持服务器开启,在 mysql 中输入如下命令:

update singers set name = 'leehom' where id = 1;


再在 shell 请求此服务和打印的结果:

curl http://localhost:8888
(jay,)


好的,bug 出现了!那么有两种方式解决它,第一种是重启服务器,这种方法可以忽略了。第二种就是将代码修改成这种方式:

1
2
3
4
cur = conn.cursor()
cur.EⅩEcute("select name from singers Where `id` = 1")
res = cur.fetchone()
print res
1
2
3
4
5
cur = conn.cursor()
cur.EⅩEcute("select name from singers Where `id` = 1")
res = cur.fetchone()
conn.commit()
print res

注意那条 commit 语句,本文其余部分解读此问题原因。




什么是事务


事务(Transaction)是并发控制的基本单位。是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位。


比如一个表在更新插入语句中,会经历 a,b,c,d,e 五个状态,那么如果我将 b-

声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系 [邮箱地址] 删除

路过

雷人

握手

鲜花

鸡蛋

相关分类

返回顶部