数据库 之 事务控制和隔离级别

1  概述

事务是指一组原子性的SQL查询、或者是一个或多个SQL语句组成的独立工作单元;MyISAM不流行的原因很大是因为其不支持事务的处理功能。

2  事务日志

事务日志定义属性,有些参数可以运行时修改,写入在配置段里,事务日志相当于是中间的辅助功能,而且很关键。

事务日志表示把操作过程一笔一笔记录下来。如某个线程要对某个行操作,数据库会先保留老版本于事务日志中,对文件的写入,新版本的内容是先写入到日志里,提交前,数据在日志文件中,而不是在数据文件中,提交操作执行后,才将新旧版本的日志清除。

执行事务时,每个操作都需要从内存读入到日志中

事务日志主要是为了加速操作,同时为了辅助提交数据的功能,将随机写操作转换为顺序写操作

事务日志必须是固定大小,一般是有两个空间,一旦一个空间满了,就写入磁盘,另一个空间开始写入。轮替工作。

为了避免事务日志所在的磁盘,因硬盘故障导致破坏,可以用raid或者镜像组同步写入两份文件,保证了冗余,实现数据安全

以下是配置文件里事务日志的相关参数:

innodb_log_files_in_group:表示一组内有几个文件,一般要有两个

innodb_log_group_home_dir:指明家目录

innodb_log_file_size:指定日志文件的大小,默认5M

innodb_mirrored_log_groups:日志组有几个

3  ACID测试

如果一个存储引擎支持事务,那么关系型数据库就必须满足ACID测试:而非关系型数据库是base(碱性的单词)

A:AUTOMICITY,原子性;整个事务中的所有操作要么全部成功执行,要么全部失败后回滚到开始处;

C:CONSISTENCY,一致性;数据库总是应该从一个一致性状态转为另一个一致性状态;

I:ISOLATION,隔离性;一个事务所做出的操作在提交之前,是否能为其它事务可见;出于保证并发操作之目的,隔离有多种级别; 隔离如果做得严格,可能导致串行执行,而失去了并发执行的意义。有四个级别,隔离性最低,并发性最高,隔离性最高,安全性也最高,但是并发性就最低。可以根据安全性和服务器的并发性选择一个合适的方案。

D:DURABILITY,持久性;事务一旦提交,其所做出的修改会永久保存;

4  事务控制

自动提交:单语句事务,影响性能

mysql> SELECT @@autocommit;#查看自动提交功能参数

mysql> SET @@session.autocommit=0;#关闭自动提交功能后需要手动控制事务

手动控制事务,事务一旦提交,就不能回滚:

启动事务:START TRANSACTION

提交事务:COMMIT

回滚事务:ROLLBACK

事务支持savepoints:保存点,相当于是虚拟机的快照

SAVEPOINT identifier#创建保存点

ROLLBACK [WORK] TO [SAVEPOINT] identifier #还原到某个保存点

RELEASE SAVEPOINT identifier#销毁savepoint

例子

MariaDB [sunny]> insert into classlist values ("su",10,"91"),("chen",18,"88");MariaDB [sunny]>

#创建保存点first

MariaDB [sunny]> savepoint first;

MariaDB [sunny]> update classlist set name=ghbsunny where nu=1;

#创建保存点second

MariaDB [sunny]> saveponit second;

如果不修改nu=1的name值,此时执行

MariaDB [sunny]> rollback to first;

#注意,执行完 rollback to first保存点second就不存在了,因为在保存点first的时候,second还没创建。一旦执行了commint后,就不能rollback

#销毁保存点first

MariaDB [sunny]> release savepoint first;

5  事务隔离级别

级别由低而高,最高级别是串行化。隔离性越来越好,但是并发性降低。低级别的事务一定有高级别的问题

mysql数据库默认是第三隔离级别REPEATABLE-READ,其他数据库一般默认第二级别READ-COMMITTED,所以mysql建议也修改为第二级别的READ-COMMITTED

查看当前会话级定义的事务隔离级别

MariaDB [sunny]> select @@session.tx_isolation;

mysql有四个隔离级别,如下:

READ-UNCOMMITTED:

读未提交 --> 容易导致脏读,不被确认的结果也可能被读取;即没有提交的情况下,别人也可以看到未提交的更新的记录

例子:打开两个crt窗口,登录mysql,分别关闭自动提交功能和设置隔离级别为READ-UNCOMMITTED

MariaDB [sunny]> SET @@session.autocommit=0;

MariaDB [sunny]> set @@session.tx_isolation="READ-UNCOMMITTED";

MariaDB [sunny]> start transaction;

在窗口1上执行

MariaDB [sunny]> update classlist set name="bf" where nu=10;

此时,窗口1没有执行commit,但是在窗口2上能够看到已经更新后的数据,即窗口2上执行如下语句,看到nu=10的name已经更改为bf了,即窗口2可以随时看到窗口1的任何修改

MariaDB [sunny]> select * from classlist where nu=10;

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

| name | nu | score |

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

| bf   | 10 | 91.00 |

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

READ-COMMITTED:

读提交--> 读别人确认的数据,可能导致不可重复读的问题,可能多次读的结果不一样;

例子:打开两个crt窗口,登录mysql,分别关闭自动提交功能和设置隔离级别为READ-COMMITTED

MariaDB [sunny]> SET @@session.autocommit=0;

MariaDB [sunny]> set @@session.tx_isolation="READ-COMMITTED";

MariaDB [sunny]> start transaction;

在窗口1上执行

MariaDB [sunny]> delete from classlist where nu=1;

此时,窗口1没有执行commit操作,窗口1上查看到的nu=1已经被删除,但是查看2还是可以看到nu=1的记录

窗口2上执行如下

MariaDB [sunny]> select * from classlist where nu=1;

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

| name  | nu | score  |

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

| sunny |  1 | 100.00 |

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

1 row in set (0.00 sec)

窗口1上执行commit后,窗口2页查看不到记录

REPEATABLE-READ:

可重复读,mysql数据库默认的隔离级别 --> 导致幻读的问题,如别的事务已经修改过数据,但是看到的还是旧数据;

例子:打开两个crt窗口,登录mysql,分别关闭自动提交功能和设置隔离级别为READ-COMMITTED

MariaDB [sunny]> SET @@session.autocommit=0;

MariaDB [sunny]> set @@session.tx_isolation="REPEATABLE-READ";

MariaDB [sunny]> start transaction;

在窗口1上执行

MariaDB [sunny]> insert into classlist values ("mei",5,99);

此时还没commit,在窗口1上可以看到新增的数据,但是窗口2上看不到新增加的数据

在窗口1上执行

MariaDB [sunny]> commit;

此时,窗口1上任然可以看到新增加的数据,但是窗口2上看不到新增的nu=5的数据,

窗口2以为没有nu=5的数据,但是窗口2要插入nu=5的数据,会出现报错重复数据的提示

MariaDB [sunny]> insert into classlist values ("mei2",5,98);

ERROR 1062 (23000): Duplicate entry '5' for key 'PRIMARY'

MariaDB [sunny]> select * from classlist;

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

| name     | nu | score |

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

| sunny    |  1 | 98.00 |

| chao     |  3 | 98.00 |

| tracy su |  6 | 95.00 |

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

如果要看到新增的数据,窗口2可以退出sql窗口,重新登录,就可以看到新增nu=5的数据

SERIALIZABLE:

串行化,隔离度最高;只有对方的事务结束(要么commit,要么rollback),另一窗口才能执行对同一表格的操作

例子:打开两个crt窗口,登录mysql,分别关闭自动提交功能和设置隔离级别为READ-COMMITTED

MariaDB [sunny]> SET @@session.autocommit=0;

MariaDB [sunny]> set @@session.tx_isolation="SERIALIZABLE";

MariaDB [sunny]> start transaction;

在窗口1上执行如下语句,但是不执行commit;自己操作后,没有确认,则别人也不能查看该表,因为已经该表琐死。只能在自己提交会回滚后,别人才能查询到结果。

delete from classlist where nu=8;

此时在窗口2上执行如下语句,那么窗口2的查询结果就出不来,等待时间超时后,就会出现报错

MariaDB [sunny]> select * from classlist;

ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

原文地址:http://blog.51cto.com/ghbsunny/2060554

时间: 2024-10-10 21:18:32

数据库 之 事务控制和隔离级别的相关文章

数据库事务特性和隔离级别

事务 一组业务操作,要么全部成功,要么全部不成功. ----------------事务的特性-------------- 原子性:一个事务是一个整体,不可分割,事务中的操作要么都成功,要么都失败. 一致性:事务必须是使数据库从一个一致性状态变到另一个一致性状态.事务执行前后,数据库的状态是一致的. 例如:A有1000,元,B有1000元,加起来是2000,中间执行转账的操作,转账后两个人的钱加起来还是2000. 隔离性:两个或多个事务并发操作,之间会互相影响.数据库提供了隔离级别来消除这些影响

数据库事务中的隔离级别和锁+spring Transactional注解

数据库事务中的隔离级别和锁 数据库事务在后端开发中占非常重要的地位,如何确保数据读取的正确性.安全性也是我们需要研究的问题. ACID 首先总结一下数据库事务正确执行的四个要素(ACID): 原子性(Atomicity):即事务是不可分割的最小工作单元,事务内的操作要么全做,要么全不做,不能只做一部分:一致性(Consistency):在事务执行前数据库的数据处于正确的状态,而事务执行完成后数据库的数据还是处于正确的状态,即数据完整性约束没有被破坏:比如我们做银行转账的相关业务,A转账给B,要求

数据库事务的四大特性以及事务的隔离级别-与-Spring事务传播机制&隔离级别

本篇讲诉数据库中事务的四大特性(ACID),并且将会详细地说明事务的隔离级别. 如果一个数据库声称支持事务的操作,那么该数据库必须要具备以下四个特性: ⑴ 原子性(Atomicity) 原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚,这和前面两篇博客介绍事务的功能是一样的概念,因此事务的操作如果成功就必须要完全应用到数据库,如果操作失败则不能对数据库有任何影响. ⑵ 一致性(Consistency) 一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执

MYSQL数据库事务4种隔离级别及7种传播行为

事务的特性: 原子性:事务的不可分割,组成事务的各个逻辑单元不可分割. 一致性:事务执行的前后,数据完整性保持一致. 隔离性:事务执行不应该受到其他事务的干扰. 持久性:事务一旦结束,数据就持久化到数据库中. 查看/设置隔离级别 查看:SELECT @@tx_isolation  设置:set tx_isolation='xxx' 事务的隔离级别 如果不考虑隔离性,引发一些安全问题 隔离性:一个事务的执行,不应该受到其他事务的干扰. 脏读:一个事务读到了另一个事务未提交的数据,导致查询结果不一致

深入解析Mysql中事务的四大隔离级别及其所解决的读现象

本文详细介绍四种事务隔离级别,并通过举例的方式说明不同的级别能解决什么样的读现象.并且介绍了在关系型数据库中不同的隔离级别的实现原理. 在DBMS中,事务保证了一个操作序列可以全部都执行或者全部都不执行(原子性),从一个状态转变到另外一个状态(一致性).由于事务满足久性.所以一旦事务被提交之后,数据就能够被持久化下来,又因为事务是满足隔离性的,所以,当多个事务同时处理同一个数据的时候,多个事务直接是互不影响的,所以,在多个事务并发操作的过程中,如果控制不好隔离级别,就有可能产生脏读.不可重复读.

MySQL事务四个隔离级别

MySQL事务隔离级别详解             MySQL数据结构SQL SQL标准定义了4类隔离级别,包括了一些具体规则,用来限定事务内外的哪些改变是可见的,哪些是不可见的.低级别的隔离级一般支持更高的并发处理,并拥有更低的系统开销. Read Uncommitted (读取未提交的内容)  在该隔离级别,所有事务都可以看到其他未提交事务的执行结果.本隔离级别很少用于实际应用,因为它的性能也不比其他级别好多少.读取未提交的数据,也被称之为脏读(Dirty Read).Read Commit

MySQL数据库中的四种隔离级别

原文:MySQL数据库中的四种隔离级别 事务的隔离性比想象的要复杂,在 SQL 标准中定义了四种级别的隔离级别.通常而言,较低级别的隔离通常可以执行更高的并发,系统的开销也更低 READ UNCOMMITTED 该级别为未提交读.在该级别中,事务中的修改即使没有提交,对其他事务也都是可见的.事务可以读取未提交的数据,这也被称为脏读.这个级别会导致很多的问题,从性能上来说,它不会比其他级别好太多,但缺乏其他级别的很多好处.除非真的有非常必要的理由,在实际应用中一般很少使用. READ COMMIT

事务与Mysql隔离级别

事务 定义: 比如ABCD四个业务,作为一个事务,他们要么一起都执行完毕,要么都不执行.(只要有一个不成功,那么所有的都不可以成功) 四个特性 ACID 原子性(Atomicity) 整个事务中的所有操作,要么全都完成,要么全部不完成. 事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态. 一致性(Consistency) 事务必须保持系统处于一致的状态,不管在任何时间并发事务有多少. 比如转账,ABCDE五个人每个人初始状态 有 100元,总额是500元. 互相转账的操作

数据库并发事务控制四:postgresql数据库的锁机制二:表锁

在博文<数据库并发事务控制四:postgresql数据库的锁机制 > http://blog.csdn.net/beiigang/article/details/43302947 中后面提到: 常规锁机制可以参考pg的官方手册,章节和内容见下面 13.3. Explicit Locking http://www.postgresql.org/docs/9.4/static/explicit-locking.html 这节分为:表锁.行锁.页锁.死锁.Advisory锁(这个名字怎么翻译好???