数据库(六)—— 事务、存储引擎、锁

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/QQ2899349953/article/details/90820209

事务

一个事务是由一条或者多条SQL操作语句组成的不可分割的单元,只有当事务中的所有操作都正常执行,整个事务才能提交给数据库,要么成功,要么失败,不能出现部分成功部分失败;

基本概念

事务是一种SQL 语句的执行,要么成功,要么失败,不能出现部分成功,部分失败,具有原子性;
事务所有的SQL全部执行完,才能提交(commit)事务,将数据存储到磁盘;
我的事务执行过程中只要有SQL出现问题,那么事务就必须回滚到最初的状态;

事务的特征:ACID

A:事务的原子性;事务是一个不可分割的整体,事务必须具有原子特征,事务操作时,要么全部执行,要么全部不执行;
C:事务的一致性;一个事务执行之前和之后,数据库数据必须保持一致性状态;(比如银行转账时,金额总和不变);
I:事务的隔离性;当两个或者多个事务并发执行时,为保证数据的安全,将一个事务内的操作和其他事务隔离起来,不被其他正在执行的事务看到;
D:事务的持久性;事务完成之后,数据库保证数据库中的数据修改是永久性的,即使数据库出现故障,也能保证恢复数据;

事务隔离:MVCC

实现数据的隔离性:
表锁和行锁;

SQL的执行自动提交和手动提交过程,默认的是自动提交;

事务隔离性使用不当会照成脏数据问题:

  • 脏读:一个事务读取了另一个事务未提交的数据;(当事务A和事务B并发操作时,事务A更新数据后,事务B读取到A未提交的数据,此时事务A回滚,事务B就读取到了事务A未提交的无效的脏数据);
  • 不可重复读:一个事务操作导致另一个事务读取到前后两次不同的数据;(例如,事务A和事务B进行并发操作,事务B查询读取数据后,事务A更新操作事务B读取的数据,此时事务B继续查询数据,会发现自己前后两次读取的数据结果不一致);
  • 幻读:一个事务的操作导致另一个事务前后两次查询的结果的数量不同;(例如,事务A和事务B进行并发操作,当事务B查询读取数据后,事务A操作新增或删除了一条满足事务B的条件的数据,此时事务B再次进行查询到前一次不存在的数据或者前一次没有的数据),(事务B读取了事务A新增的内容或者读不到事务A删除的数据);

由于多个线程会请求相同的数据,事务之间通常都会用锁互相隔离,由于数据库支持不同类型的锁,因此Java JDBC支持不同级别的事务处理,它们由Connection对象指定。在JDBC中,定义了以下5种事务隔离级别:

  1. TRANSACTION_NONE。 表示不支持事务
  2. TRANSACTION_READ_UNCOMMITTED。未提交读。说明在提交前一个事务可以看到另一个事务的变化。这样读”脏”数据,不可重复读和虚读都是被允许的。
  3. TRANSACTION_READ_COMMITTED。已提交读。说明读取未提交的数据是不允许的。这个级别仍然允许不可重复读和虚读产生。
  4. TRANSACTION_REPEATABLE_READ。可重复读。说明事务保证能够再次读取相同的数据而不会失败,但虚读仍然会出现。
  5. TRANSACTION_SERIALIZABLE。可序列化/串行化。是最高的事务级别,它防止读脏数据,不可重复读和虚读。

MySQL中的事务隔离级别:

隔离级别 脏读 不可重复度 幻读
未提交读
已提交读
可重复度
串型化

需注意:事务隔离级别越高,为避免冲突所花费的性能也就越多。可以通过Connection接口下面的函数来设置事务的隔离级别:

MySQL的事务处理:

查看MySQL事务自动提交事务:

select @@autocommit;  
//0 :手动提交   1:自动提交  默认1

设置手动提交:

set autocommit = 0;

开启一个事务:begin;
提交一个事务:commit;
回滚事务:rollback;
设置一个名称为tg的保存点:savepoint tg;
回滚到tg位置保存点:rollback to tg;

查询数据库的隔离级别:

select @@TX_ISOLATION
show variables like '%isolation%';

存储引擎

MySQL最大的特点时支持插件式的存储引擎;

MyISAM引擎:

特点:不支持事务,也不支持外键,索引采用非聚集索引(数据和索引分开存储),访问快;

Myisam的三个表,文件名和表名相同,后缀不同:
.frm:存储表定义
.MYD:存储数据
.MYI:存储索引

InNoDB引擎:

支持事务、支持自动增长列、外键功能,索引采用聚集索引;

InNoDB:
.frm:存储表定义
.idb:存储数据和索引

memory引擎:

memory是使用内存来存储数据,每一个memory在磁盘上就存在一个.frm;
memory访问特别快,因为数据和索引都存储在内存中;
采用哈希结构(不能进行范围);
但是服务一旦关闭,数据就会丢失;

MYSQL不同的存储引擎有哪些区别时?以下几点回答

种类 锁机制 B-树索引 哈希索引 外键 事务 索引缓存 数据缓存
MYISAM 表锁 支持 不支持 不支持 不支持 支持 不支持
INNODB 行锁 支持 不支持 支持 支持 支持 支持
memory 表锁 支持 支持 不支持 不支持 支持 支持
  • 锁机制:表示数据库在并发请求访问的时候,多个事务在操作时,并发操作的粒度 ;
  • B-树索引和哈希索引:主要是加速SQL的查询速度;
  • 外键:子表的字段依赖父表的主键,设置两张表的依赖关系;
  • 事务:多个SQL语句,保证他们共同执行的原子操作,要么成功,要么失败,不能只成功一部分,失败需要考虑回滚事务;
  • 索引缓存和数据缓存:和MYSQL server的查询缓存相关,在没有对数据和索引做修改之前,重复查询可以不用进行磁盘I/O,读取上一次内存中查询的缓存就可以了。

MySQL设置存储引擎:

查看数据库存储引擎:

show englines;

成绩表的时候设定存储引擎:

create table xx() engine=innodb;

修改已经存在的表的存储引擎:

alter table table_name engine = innodb;

需要修改配置文件
Windows-》my.ini
Unix -》my.cof
default-storage-engine = INNODB;
修改完配置修改保存重启就可以生效

锁:

表锁、行锁、死锁、MVCC(数据多版本并发控制)

MyISAM:

支持表锁,不支持事务处理,不支持外键;
并发程度较低(因为表锁,粒度较大,多个线程的操作是串行的),但是不会引起死锁;它支持表共享的读锁和表互斥的写锁;
对MyISAM的读操作不会影响其他用户对同一张表的读操作,但是会阻塞其他用户对同一张表的写操作;对MyISAM表的写操作,则会阻塞其他用户对同一张表的读和写操作,MyISAM的读写之间互斥,写与写之间互斥,读与读之间共享;

InNoDB

支持事务、支持外键,重要的是支持行级索,并发程度高;
InNoDB实现两种类型的行锁:
共享锁:允许一个事务去读一行,阻止其他的事务获取相同的数据集的排它锁;
排它锁:允许获得排它锁的事务更新数据,组织其他事务获取相同数据集的共享锁和排它锁;

表锁和行锁的特点:
表锁:开销小、加锁块、不会出现死锁、锁粒度比较大、发生锁冲突的概率比较大,并发程度比较低;
行锁:开销大、加锁慢、会出现死锁,锁粒度比较小,发生锁冲突的概率比较小,并发程度比较高;

表锁:
行锁:InNoDB中行锁是通过给索引上的索引项加锁实现的,而不是给表中的行记录加锁,意味着如果表中行不存在索引,就无法加行级锁,这个时候InNoDB就会使用表锁实现

MySQL server实现加锁操作;

注意:可以使用select 。。。for update;可以主动的获取锁;

MVCC(数据多版本并发控制)

死锁:
行级锁会产生死锁(InNoDB)

猜你喜欢

转载自blog.csdn.net/QQ2899349953/article/details/90820209
今日推荐