Mysql 事务并发控制
-
事务
-
什么是事务
- 数据库的事务(Transaction)一种机制,一个操作序列,包含了一组数据库操作命令.
即这一组数据库命令要么都执行,要么都不执行,因此事务是一个不饿分割的工作逻辑单元,
执行dml操作的时候(insert delete update)并没有真正的影响到我们表里面的内容,直到提交当前事务;
一个事务的结束就是下一个事务的开始
- 数据库的事务(Transaction)一种机制,一个操作序列,包含了一组数据库操作命令.
-
事物的特性
- 原子性(Actomicty): 一个事务要么全部提交,要么全部回滚
- 一致性(Consistent): 事务回滚/提交前后数据库的属性不会发生改变
- 隔离性(Isolation):多个事物之间不会相互影响
- 持久性(Durable):事务一旦提交数据就会被持久化到物理层 即使系统奔溃数据也不会丢失
-
Mysql并发
-
在单处理机系统中,事务的并行执行实际上是这些并行事务轮流交叉执行,
这种并行执行方式称为交叉并发方式; -
在多处理机系统中,每个处理机可以运行一个事务,多个处理及可以同时运行多个事务,
实现事务真正的并发运行,这种并发执行方式称为同时并发方式; -
并发事务处理能大大增加数据库资源的利用率,提高数据库系统的事务吞吐量,
从而可以支持更多用户,但并发事务处理也会带来一些问题,主要包括:
- 更新丢失(Lost Update):
- 当两个或多个事务选择同一行,然后基于最初选定的值更新该行,
由于每个事务都不知道其他事务的存在,就会发生丢失更新问题,最后的工薪覆盖其他事务锁做的更新;
- 当两个或多个事务选择同一行,然后基于最初选定的值更新该行,
- 脏读(Dirty Reads):
- 另一个事务也来读取同一条记录,如果不加控制,第二个事务读取了这些脏数据,这种现象就称为脏读;
简单的说:就是一个事务读到了另一个事务尚未提交的数据;
- 另一个事务也来读取同一条记录,如果不加控制,第二个事务读取了这些脏数据,这种现象就称为脏读;
- 不可重复读(Non-Repeatable Read):
- 同一个事务中多次读取数据发生改变,这种改变由另一个事务修改或
删除了对应的记录引起的这种现象称为不可重复度;
- 同一个事务中多次读取数据发生改变,这种改变由另一个事务修改或
- 幻读(Phantom Reads):
- 当一个事务对某行执行插入或删除时,如果该行属于某个事务正在读取的行的范围,
这样导致每次返回的结果不一样,这种现象被称为幻读;
- 当一个事务对某行执行插入或删除时,如果该行属于某个事务正在读取的行的范围,
- 更新丢失(Lost Update):
-
-
并发控制(锁)
- 当用户并发访问数据库时,为了确保事务完整性和数据库一致性,需要使用锁定,
他是显示数据库并发控制的主要手段,具体地说,锁定可以防止更新丢失,脏读,不可重复读和幻读;- 锁的类型
- 读锁Read Lock(共享锁Shared Lock):是共享的,读锁相互不阻塞,但会阻塞其他写锁,多个用户可同时
读取同一个资源,互不干扰; - 写锁Write Lock(排他锁Exclusive Lock):是排他的,一个写锁会阻塞其他的写锁和读锁,在给定时间内,
只有一个用户能执行写入;
- 读锁Read Lock(共享锁Shared Lock):是共享的,读锁相互不阻塞,但会阻塞其他写锁,多个用户可同时
- 锁粒度(锁的作用范围)
- 表级锁:锁定整张表
- 行级锁:并发程度更高,维护较麻烦,会增加系统开销,容易产生死锁
- (多个用户同时更新某相同数据库时,因互相等待对方释放权限而导致双方一直处于等待状态)
行级锁只能在存储引擎级别实现,在InnoDB存储引擎中实现了行级锁,MyISAM存储引擎不支持行级锁;
- 锁分类
- 隐式锁 由存储引擎自动完成
- 显示锁 用户手动加锁(表级锁)
- 加锁:lock tables 表名 锁定类型(读方式read|写方式write)
解锁:unlock 表名;
查看锁:show status like ‘table%’;
- 锁的类型
- 当用户并发访问数据库时,为了确保事务完整性和数据库一致性,需要使用锁定,
-
事务的隔离级别
- READ-UNCOMMITTED(读未提交):事务中的修改,及时没有提交,对其他事务也是可见的,
事务可以读取未提交的数据,这也称为"脏读";最低的隔离级别
set [global|session] transaction isolation level read uncommitted;
global:适用于所有的数据库用户;
session:适用于当前运行的会话和连接; - READ-COMMITTED(读提交):一个事务开始时,只能看见已提交的事务所作的修改,因此,再次执行同样的查询,
可能得到不一样的结果,称为"不可重复读";
set [global|session] transaction isolation level read committed; - REPEATABLE-READ(可重复读):保证了在统一个事务中多次读取同样的记录的结果时一致的,可能引起"幻读",
mysql默认的隔离级别;
set [global|session] transaction isolation level repeatable read; - SERIALIZABLE(可串行化):加锁读,即事务请求不到锁就无法读,必须等到其他事务释放锁(提交,回滚)后才行;
set [global|session] transaction isolation level serializable;
- READ-UNCOMMITTED(读未提交):事务中的修改,及时没有提交,对其他事务也是可见的,
-
事务的常用操作
-
启动 start transaction;
设置保存点 savepoint 保存点;
提交
显示提交: commit
隐式提交: ddl(create drop alter)dcl(grant revoke)
回滚
显示回滚: rollback
隐式回滚: 系统非正常退出 -
select * from users; start transaction; #开始事务 savepoint a; #设置保存点a delete from users where id > 10; savepoint b; #设置保存点b update users set name = '海燕' where id = 1; #rollback to b; rollback; commit; #没有问题之后 提交 提交后之前的保存点就消失了
-
-