MySQL 事务

前言

在我们平常的开发过程中,我们经常对于一个业务流程需要执行一组SQL,但是为了确保这一组SQL要么全部执行成功,要么全部不执行,我们需要用到MySQL的事务,而在使用事务的时候我先学习了一下自定义函数和储存过程。

自定义函数

MySQL是一个非常强大的数据库软件,它除了包含许多内置函数以外,还支持自定义编写函数,以便扩展更多的功能。

语法格式

CREATE FUNCTION ( [ [, ] ] … )

RETURNS

:指定自定义函数的名称。注意,自定义函数不能与存储过程具有相同的名称。

:用于指定自定义函数的参数。这里的参数只有名称和类型,不能指定关键字 IN、OUT 和 INOUT。

RETURNS:用于声明自定义函数返回值的数据类型。其中,用于指定返回值的数据类型。

:自定义函数的主体部分,也称函数体。所有在存储过程中使用的 SQL 语句在自定义函数中同样适用,包括前面所介绍的局部变量、SET 语句、流程控制语句、游标等。除此之外,自定义函数体还必须包含一个 RETURN 语句,其中用于指定自定义函数的返回值。

在 RETURN VALUE 语句中包含 SELECT 语句时,SELECT 语句的返回结果只能是一行且只能有一列值。

注意

MySQL的有个参数log_bin_trust_function_creators,当二进制日志启用后,这个变量就会启用。它控制是否可以信任存储函数创建者,不会创建写入二进制日志引起不安全事件的存储函数。如果设置为0(默认值),用户不得创建或修改存储函数,除非它们具有除CREATE ROUTINE或ALTER ROUTINE特权之外的SUPER权限。 设置为0还强制使用DETERMINISTIC特性或READS SQL DATA或NO SQL特性声明函数的限制。 如果变量设置为1,MySQL不会对创建存储函数实施这些限制。 此变量也适用于触发器的创建。

# 查询

show variables like 'log_bin_trust_function_creators';

# 设置

set global log_bin_trust_function_creators=1;

# 如上设置只存在于当前操作,想要永久生效,需要写入到配置文件中:

# 在[mysqld]中加上 log_bin_trust_function_creators=1

示例:随机产生字符串

DELIMITER是设置分隔符(结尾符),默认MySQL的结尾符是;。

DELIMITER $$

CREATE FUNCTION rand_string(n INT)

RETURNS VARCHAR(255)

BEGIN DECLARE chars_str VARCHAR(100) DEFAULT 'abcdefghijklmnopqrstuvwxyzABCDEFJHIJKLMNOPQRSTUVWXYZ';

DECLARE return_str VARCHAR(255) DEFAULT '';

DECLARE i INT DEFAULT 0;

WHILE i < n DO

SET return_str =CONCAT(return_str,SUBSTRING(chars_str,FLOOR(1+RAND()*52),1));

SET i = i + 1;

END WHILE;

RETURN return_str;

END $$

存储过程

SQL语句需要先编译然后执行,而存储过程(Stored Procedure)是一组为了完成特定功能的SQL语句集,经编译后存储在数据库中,用户通过指定存储过程的名字并给定参数(如果该存储过程带有参数)来调用执行它。

存储过程的优点:

(1)增强SQL语言的功能和灵活性:存储过程可以用控制语句编写,有很强的灵活性,可以完成复杂的判断和较复杂的运算。

(2)标准组件式编程:存储过程被创建后,可以在程序中被多次调用,而不必重新编写该存储过程的SQL语句。而且数据库专业人员可以随时对存储过程进行修改,对应用程序源代码毫无影响。

(3)较快的执行速度:如果某一操作包含大量的Transaction-SQL代码或分别被多次执行,那么存储过程要比批处理的执行速度快很多。因为存储过程是预编译的。在首次运行一个存储过程时查询,优化器对其进行分析优化,并且给出最终被存储在系统表中的执行计划。而批处理的ransaction-SQL语句在每次运行时都要进行编译和优化,速度相对要慢一些。

(4)减少网络流量:针对同一个数据库对象的操作(如查询、修改),如果这一操作所涉及的Transaction-SQL语句被组织进存储过程,那么当在客户计算机上调用该存储过程时,网络中传送的只是该调用语句,从而大大减少网络流量并降低了网络负载。

(5)作为一种安全机制来充分利用:通过对执行某一存储过程的权限进行限制,能够实现对相应的数据的访问权限的限制,避免了非授权用户对数据的访问,保证了数据的安全

格式

CREATE PROCEDURE ( [ [, ] ] … )

BEGIN

[sql语句,sql语句]

END

过程名

存储过程的名称,默认在当前数据库中创建。若需要在特定数据库中创建存储过程,则要在名称前面加上数据库的名称,即 db_name.sp_name。

需要注意的是,名称应当尽量避免选取与 MySQL 内置函数相同的名称,否则会发生错误。

参数

存储过程根据需要可能会有输入、输出、输入输出参数,如果有多个参数用","分割开。MySQL存储过程的参数用在存储过程的定义,共有三种参数类型,IN,OUT,INOUT:

IN参数的值必须在调用存储过程时指定,在存储过程中修改该参数的值不能被返回,为默认值

OUT:该值可在存储过程内部被改变,并可返回

INOUT:调用时指定,并且可被改变和返回

过程体

过程体的开始与结束使用BEGIN与END进行标识。

示例 批量插入数据

其中 rand_string、rand_num是自定义函数。

DELIMITER $$

CREATE PROCEDURE insert_emp( START INT , max_num INT)

BEGIN

DECLARE i INT DEFAULT 0;

SET autocommit = 0;

REPEAT

SET i = i + 1;

INSERT INTO emp (empno, NAME ,age ,deptid ) VALUES ((START+i) ,rand_string(6), rand_num(30,50),rand_num(1,10000));

UNTIL i = max_num

END REPEAT;

COMMIT;

END$$

事务

MySQL事务主要用于处理操作量大,复杂度高的数据。比如说,在人员管理系统中,你删除一个人员,你既需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这样,这些数据库操作语句就构成一个事务!

在 MySQL 中只有使用了 Innodb 数据库引擎的数据库或表才支持事务。

事务处理可以用来维护数据库的完整性,保证成批的 SQL 语句要么全部执行,要么全部不执行。

事务用来管理 insert,update,delete 语句。

一般来说,事务是必须满足4个条件(ACID)::原子性(Atomicity,或称不可分割性)、一致性(Consistency)、隔离性(Isolation,又称独立性)、持久性(Durability)。

原子性:一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。

一致性:在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。

隔离性:数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。

持久性:事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。

格式

用 BEGIN, ROLLBACK, COMMIT来实现

BEGIN 开始一个事务

ROLLBACK 事务回滚

COMMIT 事务确认

直接用 SET AUTOCOMMIT来改变 MySQL 的自动提交模式:

SET AUTOCOMMIT=0 禁止自动提交

SET AUTOCOMMIT=1 开启自动提交

示例 命令行中使用事务

mysql> select * from student;

Empty set

mysql> begin;

Query OK, 0 rows affected (0.00 sec)

mysql> insert into student(id,name) values(1,"tom");

Query OK, 1 row affected (0.00 sec)

mysql> insert into student(id,name) values(2,"selly");

Query OK, 1 row affected (0.00 sec)

mysql> commit;

Query OK, 0 rows affected (0.01 sec)

mysql> select * from student;

+----+-------+

| id | name |

+----+-------+

| 1 | tom |

| 2 | selly |

+----+-------+

2 rows in set (0.03 sec)

在 MySQL 命令行的默认设置下,事务都是自动提交的,即执行 SQL 语句后就会马上执行 COMMIT 操作。因此要显式地开启一个事务务须使用命令 BEGIN 或 START TRANSACTION,或者执行命令 SET AUTOCOMMIT=0,用来禁止使用当前会话的自动提交。

并发事务遇到的问题

更新丢失(Lost Update)

当两个或多个事务选择同一行,然后基于最初选定的值更新该行时,由于每个事务都不知道其他事务的存在,就会发生丢失更新问题―一最后的更新覆盖了由其他事务所做的更新。

例如,两个程序员修改同一java文件。每程序员独立地更改其副本,然后保存更改后的副本,这样就覆盖了原始文档。最后保存其更改副本的编辑人员覆盖前一个程序员所做的更改。

如果在一个程序员完成并提交事务之前,另一个程序员不能访问同一文件,则可避免此问题。

脏读(Dirty Reads)

一个事务正在对一条记录做修改,在这个事务完成并提交前,这条记录的数据就处于不一致状态;这时,另一个事务也来读取同一条记录,如果不加控制,第二个事务读取了这些“脏”数据,并据此做进一步的处理,就会产生未提交的数据依赖关系。这种现象被形象地叫做”脏读”。

一句话:事务A读取到了事务B已修改但尚未提交的的数据,还在这个数据基础上做了操作。此时,如果B事务回滚,A读取的数据无效,不符合一致性要求。

不可重复读(Non-Repeatable Reads)

一个事务在读取某些数据后的某个时间,再次读取以前读过的数据,却发现其读出的数据已经发生了改变、或某些记录已经被删除了!这种现象就叫做“不可重复读”。

一句话:事务A读取到了事务B已经提交的修改数据,不符合隔离性

幻读(Phantom Reads)

一个事务按相同的查询条件重新读取以前检索过的数据,却发现其他事务插入了满足其查询条件的新数据,这种现象就称为“幻读”。

一句话:事务A读取到了事务B体提交的新增数据,不符合隔离性。

多说一句:幻读和脏读有点类似,脏读是事务B里面修改了数据,幻读是事务B里面新增了数据。一句话:事务A读取到了事务B体提交的新增数据,不符合隔离性。多说一句:幻读和脏读有点类似,脏读是事务B里面修改了数据,幻读是事务B里面新增了数据。

事务隔离级别

脏读”、“不可重复读”和“幻读”,其实都是数据库读一致性问题,必须由数据库提供一定的事务隔离机制来解决。数据库的事务隔离越严格,并发副作用越小,但付出的代价也就越大,因为事务隔离实质上就是使事务在一定程度上“串行化”进行,这显然与“并发”是矛盾的。同时,不同的应用对读一致性和事务隔离程度的要求也是不同的,比如许多应用对“不可重复读”和“幻读”并不敏感,可能更关心数据并发访问的能力。

查看当前数据库的事务隔离级别: show variables like 'tx_isolation";

事务隔离级别

具体可参考:事务隔离级别

参考文献

mysql function 事务_MySQL 事务相关推荐

  1. mysql show 原理_mysql事务的实现原理

    此篇文章算是对mysql事务的一个总结,基本把mysql事务相关的知识点都涵盖到了,面试问来问去无非也就是这些,在了解这些之前我们先对mysql在执行的过程中  有一个整体的认识,如下图 如上图所示, ...

  2. ci mysql 事务_MySQL事务-学习笔记

    MySQL事务-学习笔记 MySQL事务 事务的意义 案例:银行转账过程 A向B转账500,A原来有1000,B有500. 分析: SQL处理过程: A 减少 500 B 增加 500 以上两点必须同 ...

  3. mysql 事务_MySQL事务

    MySQL中,事务其实是一个最小的,不可分割的工作单元,事务能够保证一个业务的完整性. 比如:我们的银行转账:a给b转账100 a---->-100 b---->+100 update u ...

  4. mysql ib_logfile 数量_Mysql 事务日志(Ib_logfile)

    mysql的innodb中事务日志ib_logfile(0/1) 概念: 事务日志或称redo日志,在mysql中默认以ib_logfile0,ib_logfile1名称存在,可以手工修改参数,调节开 ...

  5. mysql事物 总结_Mysql事务总结

    数据库 事务的特性ACID 事务(Transaction)是并发控制的基本单位. 所谓事务,它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位.例如,银行转帐工作:从一个帐 ...

  6. java mysql实现原理_MySQL事务实现原理

    MySQL事务隔离级别的实现原理 知识储备 只有InnoDB支持事务,所以这里说的事务隔离级别是指InnoDB下的事务隔离级别 隔离级别 读未提交:一个事务可以读取到另一个事务未提交的修改.这会带来脏 ...

  7. mysql+nest+嵌套事务_MySQL——事务

    事务(Transaction)是数据库区别于文件系统的重要特性之一,事务会把数据库从一种一致状态转换为另一种一致状态. 关键词事务四大特性ACID MySql事务隔离级别 MVCC多版本并发控制实现方 ...

  8. mysql测试事务_MySQL事务测试

    mysql事务测试 1.打开mysql的命令行,将自动提交事务给关闭 --查看是否是自动提交 1表示开启,0表示关闭 select @@autocommit; --设置关闭 set autocommi ...

  9. mysql 开启事物_mysql事务的开启

    mysql事务的开启 对于一个MYSQL数据库(InnoDB),事务的开启与提交模式无非下面这两种情况: 1>若参数autocommit=0,事务则在用户本次对数据进行操作时自动开启,在用户执行 ...

最新文章

  1. php 复选框 数组,php数组的复选框
  2. ZOJ 3728 Collision
  3. 1113 Integer Set Partition (25 分)【难度: 一般 / 知识点: 思维 贪心】
  4. 解决网络请求的依赖关系
  5. 清华计算机学院吴建平,吴建平
  6. 机房收费系统的合作版
  7. soapUI-JDBC Request
  8. HTML5清爽简洁外贸网站模板
  9. 我们来说一说TCP神奇的40ms
  10. html中使用style设置背景
  11. Java 蹒跚自学之 第八日 数组 二分查找法
  12. 基于OpenCV的计算机视觉入门(4)线段和形状的绘制
  13. c++ vector api summary
  14. FaceBook ATC 弱网测试工具环境搭建
  15. Eclipse maven构建springmvc项目
  16. NeatUpload IIS6.0注册问题
  17. 什么是用户故事 (User Story)?
  18. Typora恢复文件,找回忘记保存的记录
  19. 电脑登陆网页显示服务器出错,为什么新浪微博用电脑登陆总是提示网络错误
  20. 关于三栏式布局的几种方式

热门文章

  1. crazy pony_My Little Pony的11个DevOps课程
  2. bash 别名_必不可少的Bash别名
  3. linux使用find命令_如何在Linux中使用FIND
  4. 简单有趣的web项目_有趣而简单的电子项目书
  5. Bootstrap3 警告框插件的使用方法
  6. Bootstrap3 工具提示插件的使用方法
  7. Git笔记(27) 储藏与清理
  8. linux线程能删除自身吗,Linux内核本身和进程的区别 内核线程、用户进程、用户...
  9. php 如何让html表单当中的数据在修改mysql的时候自动变更_怎么用php把html表单内容写入数据库?...
  10. linux利用* vim提权,Linux使用suid vim.basic文件实现提权