栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Mysql事务

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Mysql事务

事务

是数据库操作的最小工作单元,是作为单个逻辑工作单元执行的一系列操作;这些操作作为一个整体一起向系统提交,要么都执行、要么都不执行;事务是一组不可再分割的操作集合(工作逻辑单元)

事务的基本特性

ACID

1.1. 原子性 (Atomicity)
事务开始后所有操作,要么全部做完,要么全部不做,不可能有半过程后再无其他操作。事务执行过程中出错,会回滚到事务开始前的状态,所有的操作就像没有发生一样。也就是说事务是一个不可分割的整体,就像化学中学过的原子,是物质构成的基本单位。

1.2. 一致性 (Consistency)
从宏观的角度来说,事务开始前和结束后,数据的完整性约束没有被破坏 。从微观的角度说,事务内的每一条子事务都按部就班完成。一致性着重取决于业务代码,

1.3. 隔离性 (Isolation)
同一时间,只允许一个事务请求同一数据,不同的事务之间彼此没有任何干扰。不同的隔离级别会有不同的效果。

1.4. 持久性 (Durability)
事务完成后,事务对数据库的所有更新将被保存到数据库,不能回滚。

事务的提交及回滚
* 先建立一个测试表user

CREATE TABLE `user`(
id INT PRIMARY KEY AUTO_INCREMENT,
`name` VARCHAR(8),
`balance` DECIMAL(10,2)
);
* 插入测试数据
INSERT INTO `user` VALUES (1,'李明',5000),(2,'小李',80000);

BEGIN; //开启事务(START TRANSACTION)
 UPDATe `user` SET balance = balance-2000 WHERe id=1;
 UPDATE `user` SET balance =balance+2000 WHERe id=2;
 COMMIT;//改变


BEGIN; 
 UPDATE `user` SET balance = balance-2000 WHERe id=1;
 UPDATE `user` SET balance =balance+2000 WHERe id=2;
ROLLBACK;//回滚 未改变
事务隔离等级

隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也很大。

事务隔离级别脏读不可重复读的幻读
未提交读YYY
已提交读NYY
可重复读NNY
串行化NNN

隔离级别越高,性能越差
mysql默认的隔离级别是 repeatable-read

未提交读 (read-uncommitted)

最低的事务隔离级别,所有事务都可以看到其他未提交事务的执行结果。读取未提交的数据,也被称之为脏读(Dirty Read)。该级别用的很少。
已提交读 (read-committed)

这是大多数数据库系统的默认隔离级别(但不是MySQL默认的)。它满足了隔离的简单定义:一个事务只能看见已经提交事务所做的改变,换句话说就是事务提交之前对其余事务不可见,但是会导致不可重复读的问题。
可重复读 (repeatable-read)

是mysql默认使用的事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行。不过理论上,这会导致另一个棘手的问题:幻读 (Phantom Read)。简单的说,幻读指当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影” 行。
串行化 (serializable)

它强制事务都是串行执行的,使之不可能相互冲突,从而解决幻读问题。换言之,它是在每个读的数据行上加上共享锁。在这个级别,可能导致大量的超时现象和锁竞争。

并发的事务问题

1.脏读
读取到的是并未完成commit的数据,很不安全
例子:id=1的有3000余额,向2号id的人转账,转完之后并没有进行提交
这时2号查询自己账户发现3000已经转过来了
此时1号在输入rollback回滚,账户钱则回到了自己的账户
事务B能够读取事务A更新但未提交的数据,然后A回滚操作,那么B读取到的数据是脏数据。
首先,先把mysql默认事务开启关闭

SELECT @@autocommit;//显示为1为自动提交

默认事务开启:当我们执行一句sql时,效果就会立即体现出来,且不能回滚

默认事务关闭

SET autocommit=0;

查询mysql隔离级别

SELECT @@global.transaction_isolation; //系统级别
SELECT @@session.transaction_isolation; //会话级别

SESSION ,GLOBAL用来指定修改隔离级别的范围
SESSION表示修改的事务隔离级别应用于当前Session(当前cmd下)中的所有事务
GLOBAL表示修改的事务隔离级别应用于所有Session(全局)中的所有事务,且当前已存在的session不受影响

修改mysql隔离级别为未提交读

SET GLOBAL TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
#1号操作...(事务A)
BEGIN;
SELECT * FROM `user` WHERe id=1;
UPDATe `user` SET balance=balance-3000;
UPDATE `user` SET balance=balance+3000;
#2号操作..(事务B)
BEGIN;
SELECT * FROM `user` WHERe id=2;
commit;
#1号操作....
ROLLBACK;

2.不可重复读
修改mysql隔离级别为读已提交

SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;
#1号操作 查找账户余额
BEGIN;
SELECt * FROM `user` WHERe id=1;
#2号此时操作 将1号账户余额转出2000
BEGIN;
UPDATe `user` SET balance = balance+2000 WHERe id=2;
UPDATE `user` SET balance = balance-2000 WHERe id=1;
COMMIT;
#此时1号再次查账户,发现余额被取走了
SELECT * FROM `user` WHERe id=1;
COMMIT;

已提交读隔离级别解决了脏读的问题,但是出现了不可重复读的问题,即事务A在两次查询的数据不一致,因为在两次查询之间事务B更新了一条数据。已提交读只允许读取已提交的记录,但不要求可重复读。
3.幻读

4.串行化
serializable完全锁定字段,若一个事务来查询同一份数据就必须等待,直到前一个事务完成并解除锁定为止。是完整的隔离级别,会锁定对应的数据表格,因而会有效率的问题。

排队,依次进行。

------------------------博客只是对个人学习做一个笔记,如有技术或侵权问题感谢纠正。------------------------
部分摘自链接:https://blog.csdn.net/qq_33710903/article/details/109644177

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/602346.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号