事务是数据库管理系统执行过程中的一个逻辑单位,有一个有限的数据库操作序列构成。mysql 的存储引擎中只有InnoDB支持事务。
什么时候会开启事务:客户端工具查看事务是否自动提交方式:SHOW GLOBAL VARIABLES LIKE "%autocommit%";有Global 和 session 两个级别。on 表示自动开启事务和提交事务。手动开启事务方式:使用 begin;或start transcation;命令。手动结束事务的话使用 commit;或者 rollback;进行回滚。提交回滚之后事务将结束。
事务带来的问题:
如果多个线程都开启自己的事务操作数据库中数据时,如果不考虑隔离性,将会出现如下问题:
比如有两个事务,一个事务在开启事务后进行转账操作,在完成对方账户转入时,自身账户还未完成扣款操作时,两个账户信息的数据被其他事务查询到,此时称为脏读。
比如 银行在查询A账户余额时,第一次查询余额200,打印了一份报告。此时他人给A账户转入100并进行提交;银行再次查询A余额发现为300,再次打印其他报告时,与之前报告中的余额显示不一样。
不可重复读和脏读的区别是:脏读是读取了其他事务未提交的数据;不可重复读是读取了其他事务中已提交的数据;
在一个事务中,同样的查询范围,由于其他事务的插入操作,使得第一次查询和第二次查询的结果集数量不一样引起的称之为幻读。MySQL中三种锁的特点?
事务的隔离级别
MVCC的思想实际为可以查到当前事务开启前数据的信息,开启事务后,其他事务对该数据所做的任何修改删除,当前该事务是查询不到的。
在InnoDB中,InnoDB为我们每行记录都添加了两个隐藏字段。数据库事务锁,
DB_TRX_ID 6字节,记录了当前的事务编号,新开事务编号都是递增的。
DB_ROLL_PTR 7字节:用于记录数据被删除,或者被更新后成为历史记录数据。存放的也是当前的事务编号。
例如:如上表格,是我们在经过
第一次创建了两个记录(事务编号1)(创建版本号都是1,删除版本 undefined);
第二次另新开启一个查询事务(事务编号2)(版本号为2,查询结果为步骤一的两条);
第三次另新开启事务(事务编号3),新增一条记录(版本号为3的记录)
第四次另新开启事务(事务编号4) 删除id为2的记录(id为2的记录中删除版本号更新为当前事务编号4);
第五次另新开启事务(事务编号5) 对id为1 的数据进行修改name列,则更新之前记录的删除版本为5,并将当前更新的记录新增创建版本设置为5.
当后面第三四五次操作之后,每次在第二步事务中查询,数据都是之前第一步中新增的两个数据。因为他每次查询都只查询事务编号小于等于2的记录。
共享锁(Shared Locks):我们获取了一行数据的读锁后,我们可以用来读取数据,所以也称为读锁。深入理解java虚拟机?手工加锁:select xxxx where ... lock in share mode;
排它锁(Exclusive Locks):排它锁是用来写数据的,所以也叫作写锁。只要一个事务获取了一行数据的写锁,那么其他事务就不能在获取到这行数据的读锁和排它锁。增删改都会默认加上一个排它锁。for update 也可以进行手工添加排它锁。
意向锁:意向锁为表上的锁,分为意向共享锁,和意向排他锁。当一张表中有共享锁时,则会在加共享锁之前给表加一个意向共享锁。MySQL 锁,当表中有记录需要添加排他锁时,则会给表上添加一个意向排他锁。意向锁可以用来判断表上当前是否有锁的信息。
在没有索引的表中:使用排他锁会将所有记录全部锁住,因为查询没有索引,会进行全表扫描,然后吧每一行隐藏的聚集索引都会锁起来。
有主键索引的表:使用相同的id的记录加锁,冲突。操作不同id,可以加锁成功。
使用辅助唯一索引的表:通过唯一索引加锁,主键索引也会被锁住。深入理解计算机pdf?(因为辅助索引中也存放着主键索引的值,通过主键索引然后加锁)
InnoDB的行锁,实际是通过锁住索引记录来实现的,
锁的算法:
相关概念:
有一张主键索引的表,其中有4条记录 1 4 7 10,我们称这里有4个Record;
Record 之外的区域我们成为 Gap 间隙;
间隙以及它右边的记录我们称之为临建区间。
记录锁(Record Lock):当我们对于有主键索引或者唯一索引的表进行等值查询时,精确匹配到一条记录的时候,我们使用的就是记录锁。 比如 where id = 1, 4 7 10。
间隙锁(Gap Lock): 当我们查询的记录不存在,不管我们使用的是范围查询还是等值查询,使用的都是间隙锁。如:where id>4 and id <7; where id =6;
临键锁(next-key Lock): 当我们使用了范围查询,不仅仅命中了Record记录,还包含了Gap间隙。这种情况下我们使用的就是临间锁。MySQL事务?它是mysql中默认的行锁算法。
临间锁示例:select * from t where id>5 and id <7 for update; --锁住(4,7] 和 (7,10];
select * from t where id>8 and id <=10 for update; --锁住 (7,10] 和 (10,+无穷);
Mysql 事务隔离级别 默认 RR
版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。
工作时间:8:00-18:00
客服电话
电子邮件
admin@qq.com
扫码二维码
获取最新动态