MySQL数据库-MySQL事务操作(回滚)

事务用于将某些操作的多个SQL作为原子性操作,一旦有某一个出现错误,即可回滚到原来的状态,从而保证数据库数据完整性。

举例:有这样一张表

从表里可以看出张三的资金里有850元,李四的资金有632元

假如张三向李四划款20元,那么张三的资金应该减20,李四的资金应该加20

UPDATE usr SET zij = zij - 20 WHERE yhm = '张三';
UPDATE usr SET zij = zij + 20 WHERE yhm = '李四';

可以看到张三的资金以减20,李四的资金以加20

但是如果在李四资金加的时候SQL语句出错,那么就会导致张三减少20成功,李四加上20失败,张三的资金减少了,李四资金没加上,钱就失踪了

UPDATE usr SET zij = zij - 20 WHERE yhm = '张三';
UPDATE usr2 SET zij = zij + 20 WHERE yhm = '李四';

定义一个存储过程来执行事务(回滚)

TRANSACTION表示事务

delimiter $$
DROP PROCEDURE IF EXISTS p1;
create PROCEDURE p1( -- 创建存储过程
OUT p_return_code tinyint -- out类型参数,用于返回值
)
BEGIN
DECLARE exit handler for sqlexception -- 捕捉错误,如果是sql错误就执行里面的
BEGIN
-- ERROR
set p_return_code = 1; -- 返回值1,说明sql错误
rollback; -- 回滚数据
END; DECLARE exit handler for sqlwarning -- 捕捉错误,如果是sql警告就执行里面的
BEGIN
-- WARNING
set p_return_code = 2; -- 返回值2,说明出现sql警告
rollback; -- 回滚数据
END; START TRANSACTION; -- 开始事务
-- 执行sql语句
UPDATE usr SET zij = zij - 20 WHERE yhm = '张三';
UPDATE usr2 SET zij = zij + 20 WHERE yhm = '李四';
COMMIT; -- 提交 -- SUCCESS
set p_return_code = 0; -- 返回0说明成功 END $$
delimiter ;

执行存储过程,执行事务

CALL p1(@u); -- 执行存储过程。传参接收返回值
SELECT @u; -- 查看返回值

可以看到返回1,说明sql错误,事务里的sql语句一旦有出现错误,将进行所有数据回滚,也就是无论成功的还是失败的语句都数据不变

pymysql模块,默认开启了事务(回滚),也就是说pymysql模块自动实现了事务(回滚)【重点】

还是上面的列子,将一个sql语句写错

#!/usr/bin/env python
#coding:utf-8 import tornado.ioloop
import tornado.web #导入tornado模块下的web文件
import pymysql #导入数据库模块 class khdHandler(tornado.web.RequestHandler):
def get(self): #连接数据库
conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='', db='cshi',charset='utf8')
# 创建游标
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) #获取存储过程(函数)的返回值
effect_row = cursor.execute("UPDATE usr SET zij = zij - 20 WHERE yhm = '张三'")
effect_row = cursor.execute("UPDATE usr2 SET zij = zij + 20 WHERE yhm = '李四'")
fhuizhi = cursor.fetchone()
print(fhuizhi) # 提交,不然无法保存新建或者修改的数据
conn.commit() # 关闭游标
cursor.close()
# 关闭连接
conn.close() self.write("欢迎访问") settings = { #html文件归类配置,设置一个字典
"template_path":"views", #键为template_path固定的,值为要存放HTML的文件夹名称
"static_path":"statics", #键为static_path固定的,值为要存放js和css的文件夹名称
} #路由映射
application = tornado.web.Application([ #创建一个变量等于tornado.web下的Application方法
(r"/khd", khdHandler),
],**settings) #将html文件归类配置字典,写在路由映射的第二个参数里 if __name__ == "__main__":
#内部socket运行起来
application.listen(8002) #设置端口
tornado.ioloop.IOLoop.instance().start()

当执行时可以看到,提示第二个语句表名称是错误的,但是第一个应该是执行成功的

在这种情况下,可以看到pymysql模块自动实现了事务(回滚),数据库数据没有改变

第二百八十六节,MySQL数据库-MySQL事务操作(回滚)的更多相关文章

  1. 第三百八十六节,Django+Xadmin打造上线标准的在线教育平台—HTML母版继承

    第三百八十六节,Django+Xadmin打造上线标准的在线教育平台—HTML母版继承 母板-子板-母板继承 母板继承就是访问的页面继承一个母板,将访问页面的内容引入到母板里指定的地方,组合成一个新页 ...

  2. 第一百二十六节,JavaScript,XPath操作xml节点

    第一百二十六节,JavaScript,XPath操作xml节点 学习要点: 1.IE中的XPath 2.W3C中的XPath 3.XPath跨浏览器兼容 XPath是一种节点查找手段,对比之前使用标准 ...

  3. 第二百八十五节,MySQL数据库-MySQL函数

    MySQL数据库-MySQL函数 1.MySQL内置函数 SELECT执行函数,后面跟要执行的函数 CHAR_LENGTH(str)函数:返回字符串的字符长度 -- CHAR_LENGTH(str)函 ...

  4. 第二百八十四节,MySQL数据库-MySQL触发器

    MySQL数据库-MySQL触发器 对某个表进行[增/删/改]操作的前后如果希望触发某个特定的行为时,可以使用触发器,触发器用于定制用户对表的行进行[增/删/改]前后的行为. 1.创建触发器基本语法 ...

  5. 第二百七十六节,MySQL数据库,【显示、创建、选定、删除数据库】,【用户管理、对用户增删改查以及授权】

    MySQL数据库,[显示.创建.选定.删除数据库],[用户管理.对用户增删改查以及授权] 1.显示数据库 SHOW DATABASES;显示数据库 SHOW DATABASES; mysql - 用户 ...

  6. 第二百八十九节,MySQL数据库-ORM之sqlalchemy模块操作数据库

    MySQL数据库-ORM之sqlalchemy模块操作数据库 sqlalchemy第三方模块 sqlalchemysqlalchemy是Python编程语言下的一款ORM框架,该框架建立在数据库API ...

  7. 记录一次Spring boot 搭建框架连接Mysql数据库注解事务不回滚的故障

    搭建了一个新框架,使用了spring boot 替换以简化原来繁杂的spring配置,使用Spring注解管理事务,持久层使用mybatis. 连接mysql数据库完成项目的过程中发现不支持事务,因为 ...

  8. 第二百二十六节,jQuery EasyUI,Tree(树)组件

    jQuery EasyUI,Tree(树)组件 本节课重点了解 EasyUI 中 Tree(树)组件的使用方法,这个组件依赖于 Draggable(拖 动)和 Droppable(放置)组件. 一.加 ...

  9. 第二百三十六节,Bootstrap辅组类和响应式工具

    Bootstrap辅组类和响应式工具 学习要点: 1.辅组类 2.响应式工具 本节课我们主要学习一下 Bootstrap 的辅组类和响应式工具,辅助类提供了一组类来辅 组页面设计,而响应式工具则利用媒 ...

随机推荐

  1. 编码规范:Eclipse Checkstyle配置

    http://chenzhou123520.iteye.com/blog/1627618 http://www.cnblogs.com/lanxuezaipiao/p/3202169.html

  2. 使用SplashScreenManager控件定制程序加载页面

    需要devexpress版本在12.0及以上才支持 https://www.cnblogs.com/wuhuacong/p/6112461.html 在DevExpress程序中使用SplashScr ...

  3. Hg(Mercurial)版本管理学习

    1.关闭分支,首先切到你要关闭的分支 hg commit --close-branch -m. 2.仓库ip地址改变之后,重设仓库ip 找到.hg文件夹 - hgrc文件 - 记事本打开重设 3.推分 ...

  4. 在Unity3D中连接WCF服务端

    服务端不多讲解,有一处需要改的地方.具体服务端请看WCF入门学习2-控制台做为宿主 建议实际项目不要拿去用,毕竟是mono不是原生.net.或许是个坑 由于Unity的mono版本问题不能直接用net ...

  5. 在verilog中调用VHDL模块

    习惯了自己发现一些小问题,既然发现了,就记下来吧,不然又要忘了,这是多么悲痛的领悟. 今天在用vivado进行块设计时所生成的顶层模块居然是用VHDL语言描述的,这时郁闷了,表示只看过VHDL语法但没 ...

  6. CTreeCtrl 父结点联动子结点CheckBox

    实现很简单,直接上代码: void CCheckBoxTreeDlg::OnNMClickTree1(NMHDR *pNMHDR, LRESULT *pResult) { // TODO: 在此添加控 ...

  7. 被linux线程基础折磨的点滴——还是没得到完美的答案,但至少得到了所需

    #include<sys/types.h> #include<unistd.h> #include<stdio.h> #include<stdlib.h> ...

  8. c++包管理工具conan

    Conan is a portable package manager, intended for C and C++ developers, but it is able to manage bui ...

  9. Accumulator

    Accumulator简介 Accumulator是spark提供的累加器,顾名思义,该变量只能够增加. 只有driver能获取到Accumulator的值(使用value方法),Task只能对其做增 ...

  10. C语言 · 分糖果

    历届试题 分糖果   时间限制:1.0s   内存限制:256.0MB      问题描述 有n个小朋友围坐成一圈.老师给每个小朋友随机发偶数个糖果,然后进行下面的游戏: 每个小朋友都把自己的糖果分一 ...