标签:innodb 就会 另一个 资源 0.00 结果 创建 set ack
事务:一组原子性的SQL查询,或者说一个独立工作单元。
事务日志:
在Oracle当中,被分解为redo log、undo log,及所谓重做日志和撤销日志
ACID测试:
A:atomicity,原子性;整个事务中的所有操作要么全部成功执行,要么全部失败后回滚;
C:conststency,一致性;数据库总是从一个一致性状态转换为另一个一致性状态;
I:Isolation,隔离性;一个事务所做出的操作在提交之前,是不能为其它所见;
D:durability;持久性;一但事务提交,其所做的修改会永久保存于数据库中;
隔离有多种隔离级别;
隔离级别越高,数据的安全性越高,不过它的并发能力就越低,隔离级别越低、并发性就越好,但是数据安全性差
事务:
启动事务:start transaction
结束事务:
1、comit;提交
2、rollback;回滚
注意;只有事务型存储引擎方能支持此类操作;
建议:显示请求和提交事务,而不要使用“自动提交”功能;
autocommit={1|0}
示例:
关闭autocommit
MariaDB [hellodb]> set autocommit=0;
Query OK, 0 rows affected (0.00 sec)
MariaDB [hellodb]> show variables like ‘%auto%‘;
+--------------------------------------+-------+
| Variable_name | Value |
+--------------------------------------+-------+
| auto_increment_increment | 1 |
| auto_increment_offset | 1 |
| autocommit | OFF |
+--------------------------------------+-------+
开始事务
MariaDB [hellodb]> start transaction;
删除学生表里面的stuid是18和23的学员
MariaDB [hellodb]> delete from students where stuid in (18,23);
执行rollback 回滚
MariaDB [hellodb]> rollback;
SAVEPOINT identifier
ROLLBACK [WORK] TO [SAVEPOINT] identifier
RELEASE SAVEPOINT identifier
savepoint示例:
# 开始事务
MariaDB [hellodb]> start transaction;
Query OK, 0 rows affected (0.00 sec)
# 先查看下最初的students表里面的所有内容
MariaDB [hellodb]> select * from students;
+-------+---------------+-----+--------+---------+-----------+
| StuID | Name | Age | Gender | ClassID | TeacherID |
+-------+---------------+-----+--------+---------+-----------+
| 1 | Shi Zhongyu | 22 | M | 2 | 3 |
| 2 | Shi Potian | 22 | M | 1 | 7 |
| 3 | Xie Yanke | 53 | M | 2 | 16 |
| 4 | Ding Dian | 32 | M | 4 | 4 |
| 5 | Yu Yutong | 26 | M | 3 | 1 |
| 6 | Shi Qing | 46 | M | 5 | NULL |
| 7 | Xi Ren | 19 | F | 3 | NULL |
| 8 | Lin Daiyu | 17 | F | 7 | NULL |
| 9 | Ren Yingying | 20 | F | 6 | NULL |
| 10 | Yue Lingshan | 19 | F | 3 | NULL |
| 11 | Yuan Chengzhi | 23 | M | 6 | NULL |
| 12 | Wen Qingqing | 19 | F | 1 | NULL |
| 13 | Tian Boguang | 33 | M | 2 | NULL |
| 14 | Lu Wushuang | 17 | F | 3 | NULL |
| 15 | Duan Yu | 19 | M | 4 | NULL |
| 16 | Xu Zhu | 21 | M | 1 | NULL |
| 17 | Lin Chong | 25 | M | 4 | NULL |
| 18 | Hua Rong | 23 | M | 7 | NULL |
| 19 | Xue Baochai | 18 | F | 6 | NULL |
| 20 | Diao Chan | 19 | F | 7 | NULL |
| 21 | Huang Yueying | 22 | F | 6 | NULL |
| 22 | Xiao Qiao | 20 | F | 1 | NULL |
| 23 | Ma Chao | 23 | M | 4 | NULL |
| 24 | Xu Xian | 27 | M | NULL | NULL |
| 25 | Sun Dasheng | 100 | M | NULL | NULL |
+-------+---------------+-----+--------+---------+-----------+
25 rows in set (0.00 sec)
# 执行delete语句删除学员编号为18的学员信息
MariaDB [hellodb]> delete from students where stuid=18;
Query OK, 1 row affected (0.00 sec)
# 创建一个事务还原点为sp1
MariaDB [hellodb]> savepoint sp1;
Query OK, 0 rows affected (0.00 sec)
# 插入一条信息
MariaDB [hellodb]> insert into students (name,age,gender) values(‘Jinjiao King‘,100,‘M‘);
Query OK, 1 row affected (0.00 sec)
# 创建一个事务还原点为sp2
MariaDB [hellodb]> savepoint sp2;
Query OK, 0 rows affected (0.00 sec)
# 使用update语句更新13号学员的年龄
MariaDB [hellodb]> update students set age=43 where stuid=13;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
# 上述操作做完之后查看下表是否发生变化
MariaDB [hellodb]> select * from students;
+-------+---------------+-----+--------+---------+-----------+
| StuID | Name | Age | Gender | ClassID | TeacherID |
+-------+---------------+-----+--------+---------+-----------+
| 1 | Shi Zhongyu | 22 | M | 2 | 3 |
| 2 | Shi Potian | 22 | M | 1 | 7 |
| 3 | Xie Yanke | 53 | M | 2 | 16 |
| 4 | Ding Dian | 32 | M | 4 | 4 |
| 5 | Yu Yutong | 26 | M | 3 | 1 |
| 6 | Shi Qing | 46 | M | 5 | NULL |
| 7 | Xi Ren | 19 | F | 3 | NULL |
| 8 | Lin Daiyu | 17 | F | 7 | NULL |
| 9 | Ren Yingying | 20 | F | 6 | NULL |
| 10 | Yue Lingshan | 19 | F | 3 | NULL |
| 11 | Yuan Chengzhi | 23 | M | 6 | NULL |
| 12 | Wen Qingqing | 19 | F | 1 | NULL |
| 13 | Tian Boguang | 43 | M | 2 | NULL |
| 14 | Lu Wushuang | 17 | F | 3 | NULL |
| 15 | Duan Yu | 19 | M | 4 | NULL |
| 16 | Xu Zhu | 21 | M | 1 | NULL |
| 17 | Lin Chong | 25 | M | 4 | NULL |
| 19 | Xue Baochai | 18 | F | 6 | NULL |
| 20 | Diao Chan | 19 | F | 7 | NULL |
| 21 | Huang Yueying | 22 | F | 6 | NULL |
| 22 | Xiao Qiao | 20 | F | 1 | NULL |
| 23 | Ma Chao | 23 | M | 4 | NULL |
| 24 | Xu Xian | 27 | M | NULL | NULL |
| 25 | Sun Dasheng | 100 | M | NULL | NULL |
| 26 | Jinjiao King | 100 | M | NULL | NULL |
+-------+---------------+-----+--------+---------+-----------+
25 rows in set (0.00 sec)
# 对students操作完之后,假如说其中有数据有问题,然后回到之前创建的sp2上
MariaDB [hellodb]> rollback to sp2;
Query OK, 0 rows affected (0.00 sec)
MariaDB [hellodb]> select * from students;
+-------+---------------+-----+--------+---------+-----------+
| StuID | Name | Age | Gender | ClassID | TeacherID |
+-------+---------------+-----+--------+---------+-----------+
| 1 | Shi Zhongyu | 22 | M | 2 | 3 |
| 2 | Shi Potian | 22 | M | 1 | 7 |
| 3 | Xie Yanke | 53 | M | 2 | 16 |
| 4 | Ding Dian | 32 | M | 4 | 4 |
| 5 | Yu Yutong | 26 | M | 3 | 1 |
| 6 | Shi Qing | 46 | M | 5 | NULL |
| 7 | Xi Ren | 19 | F | 3 | NULL |
| 8 | Lin Daiyu | 17 | F | 7 | NULL |
| 9 | Ren Yingying | 20 | F | 6 | NULL |
| 10 | Yue Lingshan | 19 | F | 3 | NULL |
| 11 | Yuan Chengzhi | 23 | M | 6 | NULL |
| 12 | Wen Qingqing | 19 | F | 1 | NULL |
| 13 | Tian Boguang | 33 | M | 2 | NULL |
| 14 | Lu Wushuang | 17 | F | 3 | NULL |
| 15 | Duan Yu | 19 | M | 4 | NULL |
| 16 | Xu Zhu | 21 | M | 1 | NULL |
| 17 | Lin Chong | 25 | M | 4 | NULL |
| 19 | Xue Baochai | 18 | F | 6 | NULL |
| 20 | Diao Chan | 19 | F | 7 | NULL |
| 21 | Huang Yueying | 22 | F | 6 | NULL |
| 22 | Xiao Qiao | 20 | F | 1 | NULL |
| 23 | Ma Chao | 23 | M | 4 | NULL |
| 24 | Xu Xian | 27 | M | NULL | NULL |
| 25 | Sun Dasheng | 100 | M | NULL | NULL |
| 26 | Jinjiao King | 100 | M | NULL | NULL |
+-------+---------------+-----+--------+---------+-----------+
25 rows in set (0.00 sec)
# 回滚到之前创建sp1的状态上
MariaDB [hellodb]> rollback to sp1;
Query OK, 0 rows affected (0.00 sec)
# 全部回滚到最初状态
MariaDB [hellodb]> rollback;
Query OK, 0 rows affected (0.00 sec)
事务隔离级别:
事务本身是需要隔离的,但隔离做的过于严格,任何一个事务都会阻塞其它访问同一个资源的事务,为了避免事务过多的影响其所谓的并发性,我们对事务关系型标准当中对事务的隔离等级做定义,每一种关系型数据库,都可以设定自己到底支持哪种级别,大多数数据库默认情况下都支持到第二种,但mysql支持第三级别
事务的四种隔离级别:(mysql默认是REPEATABLE READ 可重复读)
READ UNCOMMITED (读未提交)
脏读、不可重复读、幻读
READ COMMITTED (读提交)
不可重复读、幻读
REPEATABLE READ (可重读)
幻读
SERIALIZABILE (可串行化)
加锁读
可能存在问题:
脏读: 读别人未提交的数据
不可重复读: 读别人提交的数据也可以,但是别人提交以后产生一个问题查看的结果是之前看到的数据,看不到后面提交的新数据,不可重复读,两次读到的数据是不一样的
幻读: 即读取过程中,即使有其它提交的事务修改数据,仍只能读取到未修改前的旧数据。
加锁读:
tx_isolation:服务器变量,默认为REPEATABLE-READ;可在session级别进行修改
MVCC:多版本并发控制
死锁:
两个或多个事务在同一资源相互占用,并请求锁定对方占用的资源的状态;
数据库为了解决这样的问题,设计了各种死锁检测、和死锁超时时长
事务日志:
事务日志的写入类型为“追加”、因此其操作为“顺序IO”,此日志通常也被称为“预写式日志(write ahead logging)”;
innodb_log_file_size
innodb_log_files_in_group
innodb_log_group_home_dir
事务的隔离级别示例:
脏读实验:
为了实验效果多开一个会话窗口,并且两边都把autocommit自动提交事务给关闭掉
MariaDB [hellodb]> set autocommit=0;
MariaDB [hellodb]> show variables like ‘%auto%‘;
+------------------------------+-------+
| Variable_name | Value |
+------------------------------+-------+
| auto_increment_increment | 1 |
| auto_increment_offset | 1 |
| autocommit | OFF |
+------------------------------+-------+
1、把两个会话改为READ-UNCOMMITTED模式;
MariaDB [hellodb]> show global variables like ‘%isola%‘;
+---------------+-----------------+
| Variable_name | Value |
+---------------+-----------------+
| tx_isolation | REPEATABLE-READ |
+---------------+-----------------+
1 row in set (0.00 sec)
MariaDB [hellodb]> set tx_isolation=‘READ-UNCOMMITTED‘;
Query OK, 0 rows affected (0.00 sec)
在两个会话上都启用事务
MariaDB [hellodb]> start transaction;
Query OK, 0 rows affected (0.00 sec)
在第一个会话中修改students表里面的13号学员的年龄为40
MariaDB [hellodb]> update students set age=40 where stuid=13;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
MariaDB [hellodb]> select * from students where stuid=13;
+-------+--------------+-----+--------+---------+-----------+
| StuID | Name | Age | Gender | ClassID | TeacherID |
+-------+--------------+-----+--------+---------+-----------+
| 13 | Tian Boguang | 40 | M | 2 | NULL |
+-------+--------------+-----+--------+---------+-----------+
1 row in set (0.00 sec)
然后在第二个会话里面查看是不是能看到13号学员的修改后的数据库此时第一个窗口并未提交事务
MariaDB [hellodb]> select * from students where stuid=13;
+-------+--------------+-----+--------+---------+-----------+
| StuID | Name | Age | Gender | ClassID | TeacherID |
+-------+--------------+-----+--------+---------+-----------+
| 13 | Tian Boguang | 40 | M | 2 | NULL |
+-------+--------------+-----+--------+---------+-----------+
1 row in set (0.00 sec)
----------------------------------------------------------------------------------------
REPEATABLE-READ模式:
设置为REPEATABLE-READ
MariaDB [hellodb]> set tx_isolation=‘REPEATABLE-READ‘;
Query OK, 0 rows affected (0.00 sec)
删除stuid为3的学员
MariaDB [hellodb]> delete from students where stuid=3;
Query OK, 1 row affected (0.00 sec)
在第一会话提交事务
MariaDB [hellodb]> commit;
Query OK, 0 rows affected (0.00 sec)
在第一会话查询stuid为3的已经查不到了
MariaDB [hellodb]> select * from students where stuid=3;
Empty set (0.00 sec)
在第二个会话中查询还是可以查询到,这就产生了幻读,这种模式解决了不可重复读,不过还是避免不了幻读的问题
MariaDB [hellodb]> select * from students where stuid = 3;
+-------+-----------+-----+--------+---------+-----------+
| StuID | Name | Age | Gender | ClassID | TeacherID |
+-------+-----------+-----+--------+---------+-----------+
| 3 | Xie Yanke | 53 | M | 2 | 16 |
+-------+-----------+-----+--------+---------+-----------+
1 row in set (0.00 sec)
只有在第二会话中执行提交事务之后再次查询就没有出现了
MariaDB [hellodb]> commit;
Query OK, 0 rows affected (0.00 sec)
MariaDB [hellodb]> select * from students where stuid=3;
Empty set (0.00 sec)
----------------------------------------------------------------------------------
SERIALIZABLE 加锁读示例:
1、设置模式为SERIALIZABLE
MariaDB [hellodb]> set tx_isolation=‘SERIALIZABLE‘;
Query OK, 0 rows affected (0.00 sec)
2、修改stuid为14的年龄
MariaDB [hellodb]> update students set age=21 where stuid=14;
3、在本窗口查询修改结果
MariaDB [hellodb]> select * from students where stuid=14;
+-------+-------------+-----+--------+---------+-----------+
| StuID | Name | Age | Gender | ClassID | TeacherID |
+-------+-------------+-----+--------+---------+-----------+
| 14 | Lu Wushuang | 21 | F | 3 | NULL |
+-------+-------------+-----+--------+---------+-----------+
4、在第二个会话窗口查询,只要执行查询之后就会被阻塞,然后过了一定时长系统会提示超时
MariaDB [hellodb]> select * from students;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
5、第一窗口执行提交事务
MariaDB [hellodb]> commit;
Query OK, 0 rows affected (0.02 sec)
6、再在第二窗口查询,就可以查询
MariaDB [hellodb]> select * from students where stuid=14;
+-------+-------------+-----+--------+---------+-----------+
| StuID | Name | Age | Gender | ClassID | TeacherID |
+-------+-------------+-----+--------+---------+-----------+
| 14 | Lu Wushuang | 21 | F | 3 | NULL |
+-------+-------------+-----+--------+---------+-----------+
1 row in set (0.00 sec)
标签:innodb 就会 另一个 资源 0.00 结果 创建 set ack
原文地址:http://blog.51cto.com/dklwj/2299493