事务学习笔记

事务是一组访问并可能更新数据库内容的SQL组成的执行单元,是数据库并发控制和事务回滚的基本单位。

一个事务可能包含多个SQL,要么都失败,要么都成功。

事务具备4个基本属性

Atomic,同一个事务里,要么都提交,要么都回滚。

Consistency,即在事务开始之前和事务结束之后,数据库的完整性约束没有被破坏。

Isolation,并发事务间的数据时彼此隔离的。

Durablliy,事务提交后,所有的结果务必被持久化。

支持事务的引擎:InnoDB、NDBCluster、TokuDB。

不支持事务的引擎:MyISAM、MEMORY/HEAP

查看某个引擎是否支持事务:show engines\G;

显示开启事务:

START TRANSACTION

[READ WRITE]   -- 默认

[WITH CONSISTENT SNAPSHOT]  --发起一个一致性快照读,当前时刻提交的数据,都应该备份出来,从此刻起到之后的数据都不应该看得到。

[READ ONLYO]

或者BEGIN

开启/关闭自动提交

set autocommit | @@autocimmit =0|1

提交事务:

显式提交:commit

隐试提交:

BEGIN

START TRANSACTION

SET AUTOCOMMIT=1 / 其他非事务语句(DDL/DCL)。

回滚事务

显示回滚:ROLLBACK。

隐式回滚:连接端口/超时。

autocommit=0 必要吗?

好处:多语句提交时,不会每个SQL单独提交,提高TPS

麻烦:有个事务忘记提交,锁一直未释放;另一个事务长期锁等待,严重影响TPS。

如果没有事务控制的话,那么并发读写数据库会有什么隐患?

脏读:一个事务按相同的查询条件重新读取以前检索过的数据,却发现其他事务更新后达到了满足其查询条件的旧数据(此时它还未被提交),这种现象就称为“脏读”。

不可重复读:一个事务按相同的查询条件重新读取以前检索过的数据,却发现其他事务更新后达到了满足其查询条件的旧数据(此时它已被提交),这种现象就称为“不可重复读”。

幻读:一个事务按相同的查询条件重新读取以前检索过的数据,却发现其他事务插入了满足其查询条件的新数据(此时它已被提交),这种现象就被称为“幻读”。

事务隔离级别

Read Uncommitted(读未提交)隔离级别最低

允许脏读,允许事务查看其它事务所进行的未提交更改。

Read Commited(读已提交)

允许幻读,允许事务查看其它事务所进行的已提交更改。

Repeatable Read(可重复读)

消除了脏读、不可重复读、幻读,保证事务一致性。

确保每个事务的读取结构都是一样的,默认隔离级别。

Serializable(串行)隔离级别最高

串行化读,每次读都需要获得表级共享锁,读写间相互都会阻塞。

相当于MyISAM引擎,不支持并发了。

隔离级别 脏读 不可重复读 幻读
Read Uncommitted(读未提交)  可能 可能 可能
Read Commited(读已提交) 不可能 可能 可能
Repeatable read(可重复读) 不可能 不可能 不可能(InnoDB特定条件下可能)
Serializable(串行) 不可能 不可能 不可能

my.cnf配置

[mysqld]分段中,加入一行

transaction-isolation="READ-COMMITTED"  #默认值是REPEATABLE-READ

在线(全局)修改

SET [GLOBAL] TRANSACTION ISOLATION LEVEL READ COMMITTED

查看事务隔离级别

select @@tx_isolation;

或者

show variables like ‘%iso%‘;

查看当前隔离级别

SELECT @@GLOBAL.TX_ISOLATION,@@SESSION.TX_ISOLATION;

例子:

create table t1(

c1 int(11) not null,

c2 int(11) default null,

c3 int(11) default null,

primary key(c1),

key c2(c2)

)

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

| c1   | c2   |   c3 |

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

|    0 |  0   |   0  |

|    1 |  1   |   1  |

|    2 |  2   |   2  |

|    3 |  3   |   3  |

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

读未提交,Read uncommitted,RU隔离级别
session1 session2
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
begin begin
select * from t1 where c2=2
|    2 |  2   |   2  |
 
  select * from t1 where c2=2 
|    2 |  2   |   2  |
update t1 set c3=30 where c2=2  
  select * from t1 where c2=2
|    2 |  2   |   30  |
读到了t1还未提交的数据
读已提交,Read committed,RC隔离级别
session1 session2

SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED
begin begin
select * from t1 where c2=2
|    2 |  2   |   2  |
 
  select * from t1 where c2=2
|    2 |  2   |   2  |
update t1 set c3=30 where c2=2  
  select * from t1 where c2=2
|    2 |  2   |   2  |
t1未提交时,还是读取到旧数据
  select * from t1 where c2=2 for update
希望读取到最新版本,被阻塞,需等待
commit  
  select * from t1 where c2=2
|    2 |  2   |   30  |
t1提交后,读取到新数据
RC下的幻读
session1 session2
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED
begin begin
select * from t1 where c2=2
|    2 |  2   |   2  |
 
  select * from t1 where c2=2 
|    2 |  2   |   2  |
insert into t1select 4,2,2  
  select * from t1 where c2=2
|    2 |  2   |   2  |
t1未提交时,还是读取到旧数据
  select * from t1 where c2=2 for update
行锁等待
commit  
  select * from t1 where c2=2 
|    2 |  2   |   2  |
|    4 |  2   |   2  |  ==>幻读
t1提交后,是否加了for update都可以读取到新数据
可重复读,Repeatable read,RR隔离级别
session1 session2
SET SESSION TRANSACTION ISOLATION LEVEL RPEATABLE READ
begin begin
select * from t1 where c2=2
|    2 |  2   |   2  |
 
  select * from t1 where c2=2 
|    2 |  2   |   2  |
update t1 set c3=30 where c2=2;
commit;
 
  select * from t1 where c2=2
|    2 |  2   |   2  |

  select * from t1 where c2=2 for update
|    2 |  2   |   30  |
  select * from t1 where c2=2 
|    2 |  2   |   2  |
RR隔离级别可以避免幻读
session1 session2
SET SESSION TRANSACTION ISOLATION LEVEL RPEATABLE READ
begin begin
select * from t1 where c2=2
|    2 |  2   |   2  |
 
  select * from t1 where c2=2 
|    2 |  2   |   2  |
insert into t1select 4,2,2
ERROR 1250(HY000):Lock wait timeout exceeded;try restarting transaction
锁住c2=2这个gap,不允许有新的写入
 
串行,serializable
session1 session2
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE
begin begin
select * from t1 where c2=2
|    2 |  2   |   2  |
 
  select * from t1 where c2=2 
|    2 |  2   |   2  |
update t1 set c3=20 where c2=20
ERROR 1250(HY000):Lock wait timeout exceeded;try restarting transaction
 

InnoDB如何解决幻读的

1.RR级别下解决了幻读问题。

2.引入gap lock,把两条记录中间的gap锁住,避免其他事务写入。

3.存在幻读的条件:(1)<=RC级别。(2)或RR+ innodb_locks_unsafe_for_binlog=1

时间: 2024-12-22 11:26:22

事务学习笔记的相关文章

java事务学习笔记总结

通过这段时间的对java事务机制的学习,用这篇文章做个阶段性的总结,后续如果有时间,还可以深入学习和研究下分布式事务的补偿机制(目前中国只有阿里巴巴在这方面有成熟的研究成果),后续的学习成果,我也会补充到该系列文章中 一.什么是JAVA事务 通常的观念认为,事务仅与数据库相关. 事务必须服从ISO/IEC所制定的ACID原则.ACID是原子性(atomicity).一致性(consistency).隔离性 (isolation)和持久性(durability)的缩写.事务的原子性表示事务执行过程

java事务学习笔记(九)--深度剖析JTA原理与实现

通过本系列对java事务的学习,对事务的概念有了初步的了解,但是互联网的发展一日千里,数据量更是爆炸性增长,而普 通数据库也越来越成为应用系统的性能瓶颈,分布式数据库应运而生,相应的,java分布式事务JTA(Java Transaction API)也在这 种背景下产生了.有幸拜读了IBM developersWorks深度好文,加上自己的一些理解分享给各位看官,仅供大家互相交流学习. 原文地址:http://www.ibm.com/developerworks/cn/java/j-lo-jt

spring分布式事务学习笔记

最近项目中使用了分布式事务,本文及接下来两篇文章总结一下在项目中学到的知识. 分布式事务对性能有一定的影响,所以不是最佳的解决方案,能通过设计避免最好尽量避免. 分布式事务(Distributed transactions),也称作XA事务(XA是一个协议的名字),在spring中被称作global transaction,是指一个事务会涉及到不同的事务资源,比如不同的数据库,消息队列.事务资源都支持commit和rollback这样的事务控制命令. 按是否需要实现完整javaEE功能的应用服务

事务学习笔记二

通过Spring的事务管理框架,我们可以按照统一的编程模型来进行事务编程,不用关心数据访问技术以及具体访问什么类型的事务资源.再结合Spring的AOP框架,事务框架为我们带来了声明式事务.整个Spring的事务管理框架的设计原则是:让事务管理的关注点与数据访问的关注点相分离.在具体使用过程中:A)业务层使用事务的抽象API进行事务界定,不需要关心事务资源是什么,由框架实现类来管理B)数据访问层只关心数据访问API,不关心数据资源是否参加事务,有框架类来管理我们使用事务框架的基本流程是:publ

MySQL学习笔记-事务相关话题

事务机制 事务(Transaction)是数据库区别于文件系统的重要特性之一.事务会把数据库从一种一致状态转换为另一个种一致状态.在数据库提交工作时,可以确保其要么所有修改都已经保存了,要么所有修改都不保存. InnoDB存储引擎中的事务完全符合ACID的特性. 原子性(atomicity) 原子性是指整个数据库事务是不可分割的工作单位.只有使事务中所有的数据库操作执行都成功,才算整个事务成功.如果事务中任何一个SQL语句执行失败,那么已经执行成功的SQL语句也必须撤销,数据库状态应该退回到执行

《Spring3.X企业应用开发实战》学习笔记--DAO和事务

本篇是"<Spring3.X企业应用开发实战>,陈雄华 林开雄著,电子工业出版社,2012.2出版"的学习笔记的第二篇,关于DAO和事务. 本篇从DAO操作,以及事务处理的基本知识谈起,介绍事务本身,以及Spring如何通过注解实现事务. DAO 近几年持久化技术领域异常喧嚣,各种框架如雨后春笋般地冒出,Sun也连接不断的颁布了几个持久化规范. Spring对多个持久化技术提供了持久化支持,包括Hibernate,iBatis,JDO,JPA,TopLink,另外,还通过S

【JAVAWEB学习笔记】19_事务

事务 学习目标 案例-完成转账 一.事务概述 1.什么是事务 一件事情有n个组成单元 要不这n个组成单元同时成功 要不n个单元就同时失败 就是将n个组成单元放到一个事务中 2.mysql的事务 默认的事务:一条sql语句就是一个事务 默认就开启事务并提交事务 手动事务: 1)显示的开启一个事务:start transaction 2)事务提交:commit代表从开启事务到事务提交 中间的所有的sql都认为有效   真正的更新数据库 3)事务的回滚:rollback 代表事务的回滚 从开启事务到事

[原创]java WEB学习笔记93:Hibernate学习之路---Hibernate 缓存介绍,缓存级别,使用二级缓存的情况,二级缓存的架构集合缓存,二级缓存的并发策略,实现步骤,集合缓存,查询缓存,时间戳缓存

本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱好者,互联网技术发烧友 微博:伊直都在0221 QQ:951226918 -----------------------------------------------------------------------------------------------------------------

LoadRunner学习笔记--未经排版

LoadRunner学习笔记 并发用户数量: 与服务器进行交互的在线用户数量 请求响应时间 从客户端发送请求到得到整个响应的时间 一般包括网络响应时间+server的响应时间 事务相应时间 完成这个事务所用的时间 是性能测试中重点关注的指标 吞吐率 单位时间在网络上传输的数据量(吞吐量:网络上传输的数据总量) 指从server返回客户端的 是衡量网络性能的主要指标 TPS 每秒钟系统能够处理事务的数量 点击率 每秒发送的HTTP请求的数量 点击率越大对server的压力也就越大 资源利用率 对不