博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
MySQL数据库事务简介
阅读量:4290 次
发布时间:2019-05-27

本文共 2447 字,大约阅读时间需要 8 分钟。

准备:

mysql版本号:5.7 ,

库名:test

表名:student

表结构:

CREATE TABLE `student` (  `name` varchar(5) NOT NULL,  `age` int(11) DEFAULT NULL,  PRIMARY KEY (`name`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;
引擎:InnoDB

-------------------------------------------------

数据库事务(Database Transaction) ,是指作为单个逻辑工作单元执行的一系列操作(一般是一组SQL语句),要么完全地执行,要么完全地不执行。 

一个逻辑工作单元要成为事务,必须满足所谓的ACID(原子性、一致性、隔离性和持久性)属性。事务是数据库运行中的一个逻辑工作单位,由DBMS中的事务管理子系统负责事务的处理。

●  Atomic(原子性):事务中包含的操作被看做一个逻辑单元,这个逻辑单元中的操作要么全部成功,要么全部失败。

●  Consistency(一致性):只有合法的数据可以被写入数据库,否则事务应该将其回滚到最初状态。
●   Isolation(隔离性):事务允许多个用户对同一个数据进行并发访问,而不破坏数据的正确性和完整性。同时,并行事务的修改必须与其他并行事务的修改相互独立。更多见下文隔离级别一节
●  Durability(持久性):事务结束后,事务处理的结果必须能够得到固化。

一.语句执行

要想使用事物,必须选择正确的引擎,如InnoDB,Falcon。MyISAM等不支持事务。

1.默认:MySQL使用自动提交模式,即把每条SQL语句都当作一个事物。

下面代码第一行会插入到表中:

INSERT INTO student(name,age) VALUES ('Jack',12);INSERT INTO student(name,age) VALUES ('Koko',121222222222222222222222);

2.使用事务:以BEGIN开始,最后以COMMIT提交,使用ROOLLBACK恢复到起始点。

下面代码两行都不会插入表中:

BEGIN  INSERT INTO student(name,age) VALUES ('Mary',12);  INSERT INTO student(name,age) VALUES ('Li',121222222222222222222222);COMMIT;

二.事物的保存点

如果你想用ROOLBACK回到特定的保存点而不是BEGIN以前,使用SAVEPOINT;

语法:

SAVEPOINT  xxx;

ROOLBACK   TO  SAVEPOINT xxx;

三.事物的隔离级别

1.MyISAM和InnoDB的对并发使用的策略:

2.一个事物修改数据 / 另一个事物读取事物 时发生的问题:

--更新丢失:两个事务都同时更新一行数据,一个事务对数据的更新把另一个事务对数据的更新覆盖了。这是因为系统没有执行任何的锁操作,因此并发事务并没有被隔离开来。InnoDB引擎实现了行级锁,不会出现这种情况

--脏读:脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。因为这个数据是还没有提交的数据,那么另外一个事务读到的这个数据是脏数据,依据脏数据所做的操作可能是不正确的。

--不可重复读:在一个事务内,多次读同一个数据。在这个事务还没有结束时,另一个事务也访问该同一数据。那么,在第一个事务的两次读数据之间。由于第二个事务的修改,那么第一个事务读到的数据可能不一样,这样就发生了在一个事务内两次读到的数据是不一样的,因此称为不可重复读,即原始读取不可重复。

--幻读:第一个事务对一个表中的数据进行了修改,比如这种修改涉及到表中的“全部数据行”。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入“一行新数据”。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样。

*****不可重复读 和 幻读 区别:

不可重复读重点是修改数据,幻读重点是增加或删除数据行

从解决办法来看:

对于前者, 只需要锁住满足条件的记录

对于后者, 要锁住满足条件及其相近的记录

3.隔离级别

读未提交(Read Uncommitted):允许脏读取,但不允许更新丢失。如果一个事务已经开始写数据,则另外一个事务则不允许同时进行操作,但允许其他事务此行数据。该隔离级别可以通过“排他写锁”实现。

读提交(Read Committed):允许不可重复读取,但不允许脏读取。读取数据的事务允许其他事务继续访问该行数据,但是未提交的写事务将会禁止其他事务访问该行这可以通过“瞬间共享读锁”和“排他写锁”实现
可重复读取(Repeatable Read):禁止不可重复读取和脏读取,但是有时可能出现幻读数据。这可以通过“共享读锁”和“排他写锁”实现。读取数据的事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务
序列化(Serializable):提供严格的事务隔离。它要求事务序列化执行,事务只能一个接着一个地执行,不能并发执行。仅仅通过“行级锁”是无法实现事务序列化的,必须通过其他机制保证新插入的数据不会被刚执行查询操作的事务访问到。

隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。对于多数应用程序,可以优先考虑把数据库系统的隔离级别设为Read Committed。它能够避免脏读取,而且具有较好的并发性能。尽管它会导致不可重复读、幻读和第二类丢失更新这些并发问题,在可能出现这类问题的个别场合,可以由应用程序采用悲观锁或乐观锁来控制

你可能感兴趣的文章
Android中热修复框架AndFix原理解析及案例使用
查看>>
手写代码实现EventBus
查看>>
关于JSON的相关知识
查看>>
SpringMVC基础_常用注解
查看>>
Spring框架-IOC容器和Bean的配置(1)
查看>>
查询内容在网页里面分页显示+跳页查看
查看>>
mysql substring函数截取值后赋给一个declare变量
查看>>
Java Thread 的 sleep() 和 wait() 的区别
查看>>
DbUtils入门
查看>>
每一个程序员需要了解的10个Linux命令
查看>>
service的自调用 VS service之间调用
查看>>
Android权限管理之Permission权限机制及使用
查看>>
重识Retrofit
查看>>
PowerDesigner(数据建模)使用大全
查看>>
RadioButton与CheckBox_优就业
查看>>
java中的throw与throws的区别
查看>>
优化用户登录体验效果
查看>>
用js批量选中功能实现更改数据库中status状态值_优就业
查看>>
MySql表信息基础知识学习
查看>>
为什么document找到的不是html节点_优就业
查看>>