您现在的位置是:亿华云 > IT科技
图解 & 深入浅出JavaWeb:事务必会必知
亿华云2025-10-09 11:04:50【IT科技】0人已围观
简介事务,大家所熟悉的事务(Transcation),基本上会就往Spring事务靠。其实Spring事务管理基于底层数据库本身的事务处理机制。数据库事务的基础,是掌握Spring事务管理的基础。这篇总结
事务,图解大家所熟悉的深入b事事务(Transcation),基本上会就往Spring事务靠。浅出其实Spring事务管理基于底层数据库本身的图解事务处理机制。数据库事务的深入b事基础,是浅出掌握Spring事务管理的基础。这篇总结下数据库事务。图解
一、深入b事数据库事务
它的浅出思想:we are 伐木累。就是图解多个SQL语句(一个团队),要么所有执行success,深入b事不然就fail。浅出
它最终的图解目标:数据不会被破坏。即事务操作成功,深入b事数据的浅出结果和业务期待的结果是一致的。这也就是ACID中的一致性(Consistency)。那什么是ACID呢?
二、ACID
上面是思想,云南idc服务商牛人马上根据思想建模,DBMS中数据库事务满足4各特性,即原子性、一致性、隔离性和持久性。下面一一生动解释:
a)原子性
原子是物质的最小单元,即不可再分。
例如,以MySQL为例,每一个简单的 SQL 语句即包含在一个事务中,具有原子性。这时候有人问了,那多个SQL呢?
BEGIN TRANSACTION; INSERT INTO `test`.`city` (`state`, `country`, `name`) VALUES (1, China, CHINA,错误语句多了个VALUE); INSERT INTO `test`.`city` (`state`, `country`, `name`) VALUES (1, China, CHINA); COMMIT;结果:执行不通过。行3-5:为一个错误SQL。行6-8:是一个正确的SQL。它们各自被包裹在各自的隐式事务中,即Read Uncommited。T-all包裹了上面具有原子性的T-1和T-2,实现了更大的原子,如下图。
b)一致性
***目标:数据不会被破坏。(这不是废话?确实有点)具体说,事务操作成功后,数据库所处的免费信息发布网状态和它的业务规则是一致的,即数据不会被破坏。举个栗子:两句UPDATE语句,从A账户转账到B账户,不管成功失败,A和B账户的总额是不变的。
c)隔离性
隔离:表示互不干扰。事务与事务之间无法干扰,即每个事务独立,不会交叉。这样可以让多个线程并发访问数据库。如图:
但是聪明的小伙伴知道,如果事务完全隔离,每次只允许一个事务能访问数据库,那其他都是阻塞。会非常慢。
但是聪明的小伙伴也知道,这样会造成数据的并发问题。(是的,源码库在下面第三节讲)。
d)持久性
数据必须持久化到数据库(存储在磁盘)中。已提交的事务,即使在提交后数据库崩溃,重启数据库时也能够根据日志对未持久化的数据进行重执行操作。(同学会问,那没提交的事务呢?那就悲剧了(>﹏<))
小结:数据的一致性是最终目标,其他特性都是其要求或手段。
三、隔离性中的问题:脏读、不可重复读和幻读
对应上面的隔离性,事务并发访问的时候会出现:脏读、不可重复读和幻读。案例转自勇哥博客
脏读:A事务读取了B事务未提交的更改数据。一般数据库事务默认不允许该问题出现。
比如这里查询应该是1500,现在出现了脏读。
时间事务 A(存款)事务 B(取款)
T1开始事务
T2
开始事务
T3
查询余额(1000 元)
T4
取出 1000 元(余额 0 元)
T5查询余额(0 元)
T6
撤销事务(余额恢复为 1000 元)
T7存入 500 元(余额 500 元)
T8提交事务
不可重复读:A事务读取了B事务已提交的更改数据。
幻读:A事务读取了B事务提交的新增数据。
上面的案例脑补吧,主要还是看下面。
不可重复读和幻读区别:一个更改,一个新增数据。其实两个区别在于一个是新增(insert语句),处理幻读这个操作需要加表级别的锁,将整个表锁定,防止新增数据造成幻读。另一个则是更改(update delete),这时候避免这个情况只需要添加行级锁组织该行发生变化即可。
四、事务隔离级别
既要求高的隔离性(安全性),又要求高并发性。这种是不可能的任务。根据各种锁的操作机制出现了一个事务隔离级别。即相同情况下的输入,不同隔离级别结果不同。为啥了,当然是在并发性和安全性的抉择。如图:
按着图说的,根据程序的并发性和安全性的抉择。鱼和熊掌不可兼得也~ 但分布式的时候,可以吧安全性关键的单独分布式锁。
好了,案例说了很多下面代码实战。
这段代码地址:https://github.com/JeffLi1993/jee-component-learning
五 、JDBC事务实战
下面利用MYSQL JDBC驱动连接MySQL,代码如下:
public class TransactionLevels extends BaseJDBC { public static void main(String[] args) { try { // 加载数据库驱动 Class.forName(DRIVER); // 数据库连接 Connection conn = DriverManager.getConnection(URL,USER,PWD); // 数据库元数据 DatabaseMetaData metaData = conn.getMetaData(); // 是否支持事务 boolean isSupport = metaData.supportsTransactions(); System.out.println(isSupport); // 是否支持的事务 boolean isSupportLevel = metaData.supportsTransactionIsolationLevel(Connection.TRANSACTION_SERIALIZABLE); System.out.println(isSupportLevel); // 获取默认事务 int defaultIsolation = metaData.getDefaultTransactionIsolation(); System.out.println(defaultIsolation); /** 关闭数据库连接 */ if (conn != null) { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } catch (Exception e) { e.printStackTrace(); } } }第 5、7行是连接数据库
第 9 行:获取数据库元数据,这是包含数据库连接信息
第 12 行:从元数据中,判断是否支持事务
第 15 行:从元数据中,判断是否支持事务级别 TRANSACTION_SERIALIZABLE
第 18 行:这里可以看出MySQL默认支持的事务级别是 READ_COMMITTED,默认会隔离脏读。
具体源码如下:
因此在安全性要求不高,支持高并发的情况下,选择MySQL默认事务等级。但在安全性极高,几乎不会出现高并发情况下,选择更高的事务等级。根据上小节的图一幕了然。
【本文为专栏作者“李强强”的原创稿件,转载请通过联系作者获取授权】
戳这里,看该作者更多好文
很赞哦!(58466)
上一篇:
相关文章
- 互联网其实拼的也是人脉,域名投资也是一个时效性很强的东西,一个不起眼的消息就会引起整个域名投资市场的动荡,因此拓宽自己的人脉圈,完善自己的信息获取渠道,让自己能够掌握更为多样化的信息,这样才更有助于自己的域名投资。
- 层次查询SQL性能故障不断?给你份可靠的避坑指南!
- 基于内存和 Redis 的两级 Java 缓存框架
- 当我们在谈论 CPU 指令乱序的时候,究竟在谈论什么?
- ICANN 规章禁止转移已经被记录或者在60天前内转移的域名。
- 四种SpringBoot 接口幂等性的实现方案!最后一个80%以上的开发会踩坑
- 面试问烂的MySQL四种隔离级别,看完吊打面试官!
- 关于Redis的n种妙用,不仅仅是缓存
- 域名资源有限,好域名更是有限,但机会随时都有,这取决于我们能否抓住机会。一般观点认为,国内域名注册太深,建议优先考虑外国注册人。外国注册人相对诚实,但价格差别很大,从几美元到几十美元不等。域名投资者应抓住机遇,尽早注册国外域名。
- 如何将所有MySQL数据库从旧服务器转移到新服务器上?