mysql与事务-成都创新互联网站建设

关于创新互联

多方位宣传企业产品与服务 突出企业形象

公司简介 公司的服务 荣誉资质 新闻动态 联系我们

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的事务隔离级别,直接修改这个参数就行了。

当前名称:mysql与事务
文章位置:http://kswsj.cn/article/pihsjp.html

其他资讯