数据库事务 ACID属性、数据库并发问题和四种隔离级别
数据库事务 ACID属性、数据库并发问题和四种隔离级别
数据库事务
数据库事务是一组逻辑操作单元,使数据从一种状态变换到另一种状态
一组逻辑操作单元;一个或多个DML操作
事务处理原则
保证所有事务都作为一个工作单元来执行,即使出现故障,都不能改变这种执行方式。
一个事务执行多次操作时,要么所有事务都被提交,则永久保存;要么放弃所有修改,整个事务回滚到最初状态
数据一旦提交,则不可回滚
那些操作会导致自动提交
DDL操作一旦执行,都会自动提交
DML默认情况下,一旦执行,就会自动提交
可以通过set autocommit = false的方式取消DML自动提交
默认在关闭连接时,会自动提交数据
ACID属性
事务必须满足四个属性,即原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability),即ACID四种属性。
原子性
一个事务是一个不可分割的整体,为了保证事务的总体目标,事务必须具有原子性,即当数据修改时,要么全都执行,要么全都不执行。即,不允许事务部分地完成,避免了只执行这些操作的一部分而带来的错误。
一致性
一个事务在执行之前和执行之后,数据库数据必须保持一致性。数据库的一致性状态应该满足模式锁指定的约束条件,那么在完整执行该事务后,数据库仍然处于一致性状态。
例如:银行转账,转账前后两个账户金额之和应保持不变。
隔离性
由并发事务所作的修改必须与任何其它并发事务所作的修改隔离。事务查看数据库时数据所处的状态,要么是另一并发事务修改它之前的状态,要么是另一事务修改它之后的状态,事务不会查看中间状态的数据。
例如:对任何一对事务T1和T2,对T1而言,T2要么在T1开始之前已经结束,要么在T1完成之后再开始执行。
持久性
也被称为永久性,事务完成以后,DBMS(数据库管理系统)保证它对数据库中数据的修改是永久性的,当系统或介质发生故障时,该修改也永久保持。持久性一般通过数据库备份与恢复来保证。
- 注意 严格而言,数据库事务属性都是由数据库管理系统来进行保证的,在整个应用程序的运行过程中,应用程序无须去考虑数据库的ACID实现。
一般情况下,通过执行COMMIT(提交)或ROLLBACK(回滚)语句来终止事务。当执行COMMIT语句时,自从事务启动以来对数据库所做的一切更改就成为永久性的,即被写入到磁盘,而当执行ROLLBACK语句时,自从事务启动以来对数据库所做的一切更改都会被撤销,并且数据库中内容返回到事务开始之前所处的状态。无论什么情况,在事务完成时,都能保证回到一致性状态。
数据库并发问题
如果没有锁定且多个用户同时访问一个数据库,则当他们的事务同时使用相同的数据时可能会发生问题。由于并发操作带来的数据不一致性包括:丢失数据更新、读“脏”数据(脏读)、不可重复读。
更新丢失
- 两个事务都同时更新一行数据,一个事务对数据的更新把另一个事务对数据的更新覆盖了。这是因为系统没有执行任何的锁操作,因此并发并没有被隔离开来。
脏读
- 一个事务读取到了另一事务未提交的数据操作结果。这是相当危险的,因为很可能所有的操作都被回滚。
不可重复读
- 不可重复读(Non-repeatable Reads):一个事务对同一行数据重复读取两次,但是却得到了不同的结果。
包括以下情况:
- 虚读:事务T1读取某一数据后,事务T2对其做了修改,当事务T1再次读取该数据时得到与前一次不同的值。
- 幻读:事务在操作过程中进行两次查询,第二次查询的结果包含了第一次查询中未出现的数据或者缺少了第一次查询中出现的数据。这是因为在两次查询过程中有另外一个事务插入数据造成的。
数据库事务的四种隔离级别
数据库事务的隔离级别有4个,由低到高依次为Read uncommitted 、Read committed 、Repeatable read 、Serializable ,这四个级别可以逐个解决脏读 、不可重复读 、幻读这几类问题。
不同的隔离级别对事务的处理不同。
- 读未提交数据(Read Uncommitted):只处理更新丢失。如果一个事务已经开始写数据,则不允许其他事务同时进行写操作,但允许其他事务读此行数据。可通过“排他写锁”实现。
- 读已提交数据(Read Committed):处理更新丢失、脏读。读取数据的事务允许其他事务继续访问改行数据,但是未提交的写事务将会禁止其他事务访问改行。可通过“瞬间共享读锁”和“排他写锁”实现。
- 可重复读取(Repeatable Read):处理更新丢失、脏读和不可重复读取。读取数据的事务将会禁止写事务,但允许读事务,写事务则禁止任何其他事务。可通过“共享读锁”和“排他写锁”实现。
- 序列化(串行化)(Serializable):提供严格的事务隔离。要求失去序列化执行,事务只能一个接一个地执行,不能并发执行。仅仅通过“行级锁”是无法实现事务序列化的,必须通过其他机制保证新插入的数据不会被刚执行查询操作的事务访问到。
隔离级别越高,越能保证数据的完整性和统一性,但是对并发性能的影响也越大。对于多数应用程序,可以优先考虑把数据库系统的隔离级别设为Read Committed。它能够避免脏读,而且具有较好的并发性能。尽管它会导致不可重复读、幻读和第二类丢失更新这些并发问题,在可能出现这类问题的个别场合,可以由应用程序采用悲观锁或乐观锁来控制。
- Oracle 支持的 2 种事务隔离级别:READ COMMITED, SERIALIZABLE. Oracle 默认的事务隔离级别为: READ COMMITED
- Mysql 支持 4 中事务隔离级别. Mysql 默认的事务隔离级别为: REPEATABLE READ
事务隔离级别设置
//查看当前事物级别:
SELECT @@tx_isolation;
//设置mysql的隔离级别:
//set session transaction isolation level 设置事务隔离级别
//设置read uncommitted级别:
set session transaction isolation level read uncommitted;
//设置read committed级别:
set session transaction isolation level read committed;
//设置repeatable read级别:
set session transaction isolation level repeatable read;
//设置serializable级别:
set session transaction isolation level serializable;
Java代码获取和设置隔离级别
//获取数据库事务隔离级别
int transactionIsolation = conn.getTransactionIsolation();
//设置数据库事务隔离级别;事务隔离级别:TRANSACTION_READ_COMMITTED
conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
数据库事务 ACID属性、数据库并发问题和四种隔离级别的更多相关文章
- 简单理解:数据库的一致性与四种隔离级别(+MySQL实现)
并行数据库存在着几种常见不一致问题: 1.更新丢失:两个并发的写进程同时修改某内容,一个没修改完提交之后另一个又提交,导致其覆盖了第一个提交的写进程内容. 2.脏读:一个操作读到了另外一个操作没有提交 ...
- 数据库操作事物的四大特性以及MySQL数据库的四种隔离级别
1 .事物操作数据库的四大特性(ACID) 1.原子性 (Atomicity) 原子性:就是事物的所包含的所有操作,要么全部成功,要么全部失败回滚. 2.一致性 (Consistency) 一致性:简 ...
- sql 事务的四种隔离级别
在 SQL 标准中定义了四种隔离级别,每一种级别都规定了一个事务中所做的修改,哪些在事务内和事务间是可见的,哪些是不可见的.较低级别的隔离通常可以执行更高的并发,系统的开销也更低. read unco ...
- SQL事务的四种隔离级别和MySQL多版本并发控制
SQL标准定义了4类隔离级别,包括了一些具体规则,用来限定事务内外的那些改变时可见的,那些是不可见的.低级别的隔离级一般支持更高的并发处理,并拥有更低的系统开销. ReadUncommitted( ...
- SQL Server事务的四种隔离级别
在SQL标准中定义了四种隔离级别,每一种级别都规定了一个事务中所做的修改,哪些是在事务内和事务间可见的,哪些是不可见的.较低级别的隔离通常可以执行更高的并发,系统的开销也更低. 1.未提交读(Read ...
- MySQL数据库中的四种隔离级别
事务的隔离性比想象的要复杂,在 SQL 标准中定义了四种级别的隔离级别.通常而言,较低级别的隔离通常可以执行更高的并发,系统的开销也更低 READ UNCOMMITTED 该级别为未提交读.在该级别中 ...
- mysql ACID与四种隔离级别归纳总结
关于数据库的ACID特性已经有很多的介绍,这里再重新归纳总结一下: A(atomicity)原子性: 即事务要么全部做完,要么全部不做,不会出现只做一部分的情形,如A给B转帐,不会出现A的钱少了, ...
- MySQL事务的四种隔离级别
事务的基本要素: 原子性(atomicity):事务开始后的全部操作, 要么全部执行成功,如果中间出现错误,事务回滚到事务开始前的状态. 一致性(Consistency):事务开始后,数据库的完整性约 ...
- msyql事务的四种隔离级别
一.事务的基本要素(ACID) 1.原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节.事务执行过程中出错,会回滚到事务开始前的状态,所有的操作就像没有 ...
随机推荐
- hdu2157 How many ways??
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission ...
- poj3087 Shuffle'm Up
Description A common pastime for poker players at a poker table is to shuffle stacks of chips. Shuff ...
- HDU - 3282 优先队列的使用
题意: 按照顺序给你n个数,当数的数量是奇数的时候就输出它们的中位数 题解: 优先队列默认是大顶堆,即priority_queue.top()是这个队列中的最大值 那么我们就可以先创造一个大顶堆优先队 ...
- AtCoder Beginner Contest 179 D - Leaping Tak (DP)
题意:给你一个数字\(n\)和\(k\)个区间,\(S\)表示所有区间的并的集合,你目前在\(1\),每次可以从集合中选择一个数字向右移动,问有多少种方法从\(1\)走到\(n\). 题解:我们从1开 ...
- 动态主席树【带修改】&& 例题 Dynamic Rankings ZOJ - 2112
参考链接:https://blog.csdn.net/WilliamSun0122/article/details/77885781 一.动态主席树介绍 动态主席树与静态主席树的不同在于:静态主席树不 ...
- 忘记Mysql的root用户密码处理方法(以mysql 5.5.33为例)
1.修改mysql服务器的脚本 ~]#vi /etc/rc.d/init.d/mysqld #找到$bindir/mysqld_safe --datadir="$datadir" ...
- VSCode VUE常用配置
{ // vscode默认启用了根据文件类型自动设置tabsize的选项 "editor.detectIndentation": false, // 重新设定tabsi ...
- C++ part2
为什么析构函数必须是虚函数?为什么C++默认的析构函数不是虚函数? references: nowcoder 将可能会被继承的父类的析构函数设置为虚函数,可以保证当我们new一个子类,然后使用基类指针 ...
- 卧槽,sql注入竟然把我们的系统搞挂了
前言 最近我在整理安全漏洞相关问题,准备在公司做一次分享.恰好,这段时间团队发现了一个sql注入漏洞:在一个公共的分页功能中,排序字段作为入参,前端页面可以自定义.在分页sql的mybatis map ...
- play games for learning web skills
play games for learning web skills CSS flexbox https://codepip.com/games/flexbox-froggy/ CSS grid ht ...