数据库事务简介
Posted java全栈技术
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据库事务简介相关的知识,希望对你有一定的参考价值。
1.数据库事务简介
1.1 事务的ACID特性:
A:Atomicity 原子性:事务必须 是一个不可分割的整体 , 要么全部执行,要么全部不执行。
C:Consistency:一致性 也就是说执行完数据库操作后,数据不会被破坏。比如:如果从A账户转账到B账户,不可能以为A账户扣了钱,B账户没有加钱。
I:Isolation 隔离性 比如我们编写了一条update语句,提交到数据库的一刹那,有可能别人也提交了一条delete语句到数据库中。也许我们都是对同一条记录进行操作,如果不加控制,就会出大麻烦。
D:Durability 持久性 如果执行一条insert语句后,数据库必须保证有一条永地存放 在磁盘中
原子性是基础,隔离性是手段,持久性是目睹,真正的老大 是一致性。
事务所面临的问题:
ACID 这4条特征当中,其实最难理解的不是一致性,而是隔离性。事务 隔离级别是为了解决数据在高并发下产生的问题:
Dirty Read (脏读)
Unrepeatable Read(不可重复读)
Phantom Read(幻读)
脏读:
时间 | 事务A(存款) | 事务B(取款) |
---|---|---|
T1 | 开始事务 | --- |
T2 | --- | 开始事务 |
T3 | --- | 查询余额(1000元) |
T4 | --- | 取出1000元(余额为0) |
T5 | 查询余额(0 元) | --- |
T6 | --- | 撤销事务(余额恢复为1000元) |
T7 | 存入500元(余额 500) | --- |
T8 | 提交事务 | --- |
余额应该为1500元才对。请看T5时间点,事务A此时查询余额为0,这个数据就是脏数据,它是事务B造成的,明显事务没有进行隔离。
不可重复读
时间 | 事务A(存款) | 事务B(取款) |
---|---|---|
T1 | 开始事务 | --- |
T2 | --- | 开始事务 |
T3 | --- | 查询余额(1000元) |
T4 | 查询余额(1000) | --- |
T5 | --- | 取出1000元(余额为0) |
T6 | --- | 提交事务 |
T7 | 查询余额(0元) | --- |
事务A除了查询了两次意外,其他什么事情都没有做,结果钱从1000变为0了,这就是重复读了,其实这样也是合理地,毕竟事务B提交了事务,数据库将结果进行了持久化,所以事务A再次读取时自然发生了变化。
这种现象基本上市可以理解的,但是在“变态”的场景下缺是不允许的。毕竟这种现象也是事物之间没有隔离造成的,但是我们对于这种问题似乎可以忽略。
幻读
时间 | 统计总存款 | 事务B(存款) |
---|---|---|
T1 | 开始事务 | --- |
T2 | --- | 开始事务 |
T3 | 统计总存款(10000元) | --- |
T4 | --- | 存入100元 |
T5 | --- | 提交事务 |
T6 | 统计 总存款(101000元) | --- |
归纳一下,以上提到了事务并发所引起的与读取数据有关的问题,各用一句话来描述:
脏读----事务A读取了事务B未提交的数据,并在这个基础 上又做了其他操作
不可重复读--- 事务A读取了事务B已提交的数据
幻读--- 事务A读取 了事务B已提交的新增数据
第一条是坚决抵制的,后两条在大多数情况下可以不考虑
不同的事务隔离级别能处理的事务并发问题如下表:
事务隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
READ_UNCOMMITED | 允许 | 允许 | 允许 |
READ_COMMITED | 禁止 |
允许 | 允许 |
REPEATABLE_READ | 禁止 |
禁止 |
允许 |
SERIALIZABLE | 禁止 |
禁止 |
禁止 |
JDBC也提供了这四类事务隔离级别,但默认事务隔离级别对不同的数据库产品而言却是不一样的。mysql默认的事务隔离级别是READ_COMMITTED,READ_COMMITTED 已经可以解决绝大多数问题了,其他的就具体问题具体分析了。
可以使用下面代码来获取使用的数据库的隔离 级别:
1DatabaseMetaData meta = DBUtil.getDataSource().getConnection();
2getMetaData();
3int defaultIdolation = meta.getDefaultTransactionIsolation();
数据库是怎样实现隔离级别的呢?其实就是“锁”,当插入数据时,就是锁表;当更新数据时,就锁定行,这叫锁行。
以上是关于数据库事务简介的主要内容,如果未能解决你的问题,请参考以下文章