微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

mysql与事务

什么是事务
事务是作为一个逻辑单元执行的一系列操作,一个逻辑工作单元必须有四个属性,称为 ACID(原子性、一致性、隔离性和持久性)属性,只有这样才能成为一个事务
一、事务的特性(ACID
原子性(Atomicity)
一组操作·要么全成功,要么全失败。
一致性(Consistency)
保证数据的正确性,合理性,完整性。事务在完成时,必须使所有的数据都保持一致状态
例如,在一次转账过程中,从某一账户中扣除的金额必须与另一账户中存入的金额相等。
隔离性(Isolation)
一个会话不能修改一个用户修改了但未提交的数据。
持久性(Durability)
一个事物一旦提交,数据库的数据所发生的变化是永久的。
二、事务的隔离级别
一般数据库中,有四种隔离级别

mysql与事务

mysql与事务
如上图,四种隔离级别分别实现了不同的功能,看是级别越高也代表着需要的锁越多,更容易产生阻塞。

接下来通过实验介绍这几种读
(1)脏读
把隔离级别调为read-uncommitted
root@localhost:mysql.sock  01:30:05 [(none)]>set global tx_isolation = 'read-uncommitted';
root@localhost:MysqL.sock  01:30:22 [(none)]>show global variables like '%iso%';
+---------------+------------------+
| Variable_name | Value            |
+---------------+------------------+
| tx_isolation  | read-uncommitted |
+---------------+------------------+
1 row in set (0.00 sec)
会话1:
root@localhost:MysqL.sock  01:34:06 [lala]>select * from score;
Empty set (0.00 sec)
root@localhost:MysqL.sock  01:34:53 [lala]>begin;
Query OK, 0 rows affected (0.00 sec)
root@localhost:MysqL.sock  01:35:23 [lala]>insert into score values(1,'xiaohong',99);
Query OK, 1 row affected (0.00 sec)
还没有提交
会话2:
root@localhost:MysqL.sock  01:37:08 [lala]>select * from score;
+------+----------+-------+
| id   | name     | score |
+------+----------+-------+
|    1 | xiaohong |    99 |
+------+----------+-------+
1 row in set (0.00 sec)
会话2可以直接读到会话1还没有提交的数据。
(2)不可重复读
root@localhost:MysqL.sock  01:30:05 [(none)]>set global tx_isolation = 'READ-COMMITTED';
root@localhost:MysqL.sock  01:30:22 [(none)]>show global variables like '%iso%';
+---------------+------------------+
| Variable_name | Value            |
+---------------+------------------+
| tx_isolation  | READ-COMMITTED |
+---------------+------------------+
1 row in set (0.00 sec)
会话1:
root@localhost:MysqL.sock  01:49:00 [lala]>begin;
Query OK, 0 rows affected (0.00 sec)

root@localhost:MysqL.sock  01:49:08 [lala]>update score set id=3;
Query OK, 1 row affected (0.00 sec)

会话2:
root@localhost:MysqL.sock  01:49:14 [lala]>select * from score;
+------+----------+-------+
| id   | name     | score |
+------+----------+-------+
|    1 | xiaohong |    99 |
+------+----------+-------+
1 row in set (0.00 sec)
会话1:
root@localhost:MysqL.sock  01:49:20 [lala]>commit;
Query OK, 0 rows affected (0.00 sec)
会话2:
root@localhost:MysqL.sock  01:49:47 [lala]>select * from score;
+------+----------+-------+
| id   | name     | score |
+------+----------+-------+
|    3 | xiaohong |    99 |
+------+----------+-------+
1 row in set (0.00 sec)
会话2第一次只读到id的值是1,但以为会话1提交,会话2第二次读到id的值是3.
(3)幻读
会话1:
root@localhost:MysqL.sock  01:49:00 [lala]>begin;
Query OK, 0 rows affected (0.00 sec)

root@localhost:MysqL.sock  01:49:08 [lala]>insert into score values(2,'xiaoming',65);
Query OK, 1 row affected (0.00 sec)

会话2:
root@localhost:MysqL.sock  01:49:14 [lala]>select * from score;
+------+----------+-------+
| id   | name     | score |
+------+----------+-------+
|    1 | xiaohong |    99 |
+------+----------+-------+
1 row in set (0.00 sec)
会话1:
root@localhost:MysqL.sock  01:49:20 [lala]>commit;
Query OK, 0 rows affected (0.00 sec)
会话2:
root@localhost:MysqL.sock  01:50:27 [lala]>select * from score;
+------+----------+-------+
| id   | name     | score |
+------+----------+-------+
|    3 | xiaohong |    99 |
|    2 | xiaoming |    65 |
+------+----------+-------+
2 rows in set (0.00 sec)
会话2第一次只读到1条数据,但以为会话1提交,会话2第二次读到两条记录

ps:不可重复读是因为数据的update导致,而幻读是因为数据的delete或者insert导致

三、MysqL中的事务
MysqL认开启事务自动提交,即每执行完一条sql语句自动提交一次。
那怎么禁用事务自动提交呢?如下:
session级别:
set autocommit=off;
局级别:
方法一:set global init_connect='set autocommit=0';
方法二:修改参数文件my.cnf
               [MysqLd]
               init_connect='set autocommit=0';
方法三:  启动MysqL服务时,加上参数 -init_connect='set autocommit=0';
也可以通过begin开启一个事务,再通过commit提交;
MysqL认隔离级别
MysqL中的innodb的事务认隔离级别是Repeatable read(可重复读),但是它不是普通的Repeatable read,它在可重复读的基础上避免了幻读。是通过臭名昭著的gop锁实现不可重复读。
myql通过tx_isolation决定事务隔离级别 ,可以查看当前的参数
root@localhost:MysqL.sock  01:17:04 [(none)]>show global variables like '%iso%';
+---------------+----------------+
| Variable_name | Value          |
+---------------+----------------+
| tx_isolation  | REPEATABLE-READ |
+---------------+----------------+
1 row in set (0.00 sec)
所以要想修改MysqL的事务隔离级别,直接修改这个参数就行了。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐