事务与锁

数据库事务( transaction)是访问并可能操作各种数据项的一个数据库操作序列,这些操作要么全部执行,要么全部不执行,是一个不可分割的工作单位。事务由事务开始与事务结束之间执行的全部数据库操作组成。即只有当事务中的所有的操作都正常执行时,整个事务才提交给数据库。

1、事务是一组SQL语句的执行,要么全部执行成功,要么全部执行失败,不能出现部分成功和失败,保证原子操作

2、事务中所有的数据执行成功,才能提交(commit)事务,把结果写入磁盘
3、事务在执行过程中,有的SQL出现了错误,那么事务必须回滚(rollback)到最初的状态

比如,我们去银行转账,操作可以分为下面两个环节: 
(1)从第一个账户取出款项。 
(2)将款项存入第二个账户。
在这个过程中,两个环节是关联的。第一个账户划出款项必须保证正确的存入第二个账户,如果第二个环节没有完成,整个的过程都应该取消,否则就会发生丢失款项的问题。整个交易过程,可以看作是一个事物,成功则全部成功,失败则需要全部撤消,这样可以避免当操作的中间环节出现问题时,产生数据不一致的问题。

 

一般来说,事务是必须满足4个条件(ACID)::原子性(Atomicity,或称不可分割性)、一致性(Consistency)、隔离性(Isolation,又称独立性)、持久性(Durability)。
 原子性:一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
 一致性:在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。
 隔离性:数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。
持久性:事务处理结束后,对数据的修改就是永久的,即便系统故障也能恢复数据。
 
 
在 MySQL 命令行的默认设置下,事务都是自动提交的,即执行 SQL 语句后就会马上执行 COMMIT 操作。
因此要显式地开启一个事务务须使用命令 BEGIN 或 START TRANSACTION,或者执行命令 SET AUTOCOMMIT=0,用来禁止使用当前会话的自动提交。
 
事务的隔离级别
  事务处理隔离级别使用不当,会引起以下问题:
  脏读(Drity Dead):一个事务读物了另一个事务未提交的数据
  例:当事务A和事务B并发执行时,当事务A更新后,事务B读取到事务A尚未提交的数据,此时事务A回滚,则事务B读取到则是无效的脏数据
  (事务B读取到事务A尚未提交的数据)
 
  不可重复读(NonRepeatable Read):一个事务的操作导致另一个事务前后两次读取到不同的数据
  例:当事务A和事务B并发执行时,当事务B查询读取数据后,事务A更新操作并更改事务读到的数据,此时事务B再次去读该数据,发现前后两次读取的数   据不一致(事务B读取事务A已提交的数据)

  幻读(Phantom Read):一个事务的操作导致另一个事务前后两次查询的结果数据量不同
  例:当事务A和事务B并发执行时,当事务B插叙读取数据后,事务A新增或者删除了一条满足事务B查询要求的数据,此时事务B再次去读数据,发现查询到   的前一次不存在的记录,或者查询的数据不见了(事务B读取到了事务A新增或者删除的数据)
  
 MySQL中存在的隔离级别:
  1、Transaction_Read_UNcommitted:未提交读
   说明在提交前一个事务可以看到另一个事务的变化,会有脏读,不可重复读,虚读都会存在
  2、Transaction_Read_committed:已提交读
  说明在提交之前的数据其他事务是不允许看到。不可重复读和虚读的问题还是会存在
  3、Transaction_Repeatable_Read:可重复读
   保证能够再次读取相同的数据而不会失败。虚读还是会存在
  4、Transaction_Serializable:可序列化/串行化
    是最高的事务隔离级别,他能够防止脏读、不可重复读、幻读的问题
四种隔离级别的对比:
-------------------------------------
隔离级别  | 脏读   | 不可重复读  |  幻读
-------------------------------------
未提交读  | 可以   |   可以     | 可以
-------------------------------------
已提交读  | 不可以  |  可以     |  可以
-------------------------------------
可重复读  | 不可以  | 不可以    |  可以
-------------------------------------
串性化    | 不可以  | 不可以    | 不可以
注意:事务隔离级别越高,为避免冲突所花费的性能也就越多  事务并不是越高越好

MySQL中事务处理的SQL:
查看事务是方式自动提交
select @@autocommit;
0 表示事务是手动提交,1表示事务自动提交(默认是自动提交)

set @@autocommit = 0;
设置事务提交的方法:0 表示事务是手动提交,1表示事务自动提交

begin:开启事务
commit:提交一个事务
rollback:回滚事务到初始状态;
 

commit命令提交之后。其他线程才能读到数据库更新之后的数据。

 

 

savapoint  t1;设置一个保存点为t1的位置
rollback to t1; 回滚到t1的保存点
关于存储引擎的其他知识见文章→→   索引及底层原理
MYSQL不同的存储引擎有哪些区别时?以下几点回答
----------------------------------------------------------------------
种类  |  锁机制  | B-树索引 | 哈希索引  |外键  |事务   | 索引缓存  | 数据缓存
----------------------------------------------------------------------
MYISAM| 表锁    |   支持   |  不支持  |不支持 |不支持 |  支持     | 不支持
----------------------------------------------------------------------
INNODB| 行锁    |   支持   |  不支持  |支持   |支持  |   支持    |  支持
----------------------------------------------------------------------
memory| 表锁    |   支持   |  支持    |不支持 | 不支持|   支持    | 支持
----------------------------------------------------------------------
 存储引擎涉及到的命令:
show engines;
数据库支持的存储引擎:
mysql> show engines\G;
*************************** 1. row ***************************
      Engine: InnoDB
     Support: DEFAULT
     Comment: Supports transactions, row-level locking, and foreign keys
Transactions: YES
          XA: YES
  Savepoints: YES
*************************** 2. row ***************************
      Engine: MRG_MYISAM
     Support: YES
     Comment: Collection of identical MyISAM tables
Transactions: NO
          XA: NO
  Savepoints: NO
*************************** 3. row ***************************
      Engine: MEMORY
     Support: YES
     Comment: Hash based, stored in memory, useful for temporary tables
Transactions: NO
          XA: NO
  Savepoints: NO
*************************** 4. row ***************************
      Engine: BLACKHOLE
     Support: YES
     Comment: /dev/null storage engine (anything you write to it disappears)
Transactions: NO
          XA: NO
  Savepoints: NO
*************************** 5. row ***************************
      Engine: MyISAM
     Support: YES
     Comment: MyISAM storage engine
Transactions: NO
          XA: NO
  Savepoints: NO
*************************** 6. row ***************************
      Engine: CSV
     Support: YES
     Comment: CSV storage engine
Transactions: NO
          XA: NO
  Savepoints: NO
*************************** 7. row ***************************
      Engine: ARCHIVE
     Support: YES
     Comment: Archive storage engine
Transactions: NO
          XA: NO
  Savepoints: NO
*************************** 8. row ***************************
      Engine: PERFORMANCE_SCHEMA
     Support: YES
     Comment: Performance Schema
Transactions: NO
          XA: NO
  Savepoints: NO
*************************** 9. row ***************************
      Engine: FEDERATED
     Support: NO
     Comment: Federated MySQL storage engine
Transactions: NULL
          XA: NULL
  Savepoints: NULL


 

创建表时指定存储引擎:
create table table_name( 属性名 类型...) engine = innodb;
在已存在的表中修改存储引擎:
alter table table_name engine = innodb;

如果对整个MySQL的存储引擎做修改,直接修改配置文件
window 中是my.ini  在Linux系统中是my.cof
D:\mysql\mysql-5.7.24-winx64(我自己电脑的存储位置)
 

 
锁:表锁,行锁,共享锁,排它锁,死锁
MyISAM表锁:
MYISAM存储存储引擎支持表锁,不支持事务处理,不支持外键
MYISAM并发比较简单,只支持表锁粒度,锁的粒度比较大
并发能力,但是不会引起死锁,它支持表共享的读锁和表互斥的写锁
对MYISAM表的读操作,不会阻塞其他用户对同一张表的读操作,但是会阻塞其他用户
对同一张表的写操作
对MYISAM表的写操作,则会阻塞其他用户对同一个表的读和写操作
MYISAM的读与写之间互斥,写与写之间互斥,读与读之间共享

INNODB行锁
INNODB支持事务,支持外键,重要的是支持行级锁(同时支持行锁和表锁,默认使用行锁),并发程度高
INNODB实现两种类型的行锁:
共享锁(S):允许一个事务去读一行,阻止其他的事务获取相同的数据集的排他锁。
排它锁(X):允许获得排他锁的事务更新数据,阻止其他事务获取相同数据集的共享读锁和排他写锁

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

行锁:INNODB中行锁是通过给索引上的索引项加锁实现的,而不是给表中的行记录加锁
意味着,如果表中的行不存在索引,INNODB使用表锁

 


 
posted @ 2019-12-08 23:23  acehm  阅读(328)  评论(0)    收藏  举报