事务与锁

摘要:
数据库事务是访问并可以操作各种数据项的一系列数据库操作。这些操作不是全部就是全部,是不可分割的工作单元。事务由事务开始和结束之间执行的所有数据库操作组成。也就是说,只有当事务中的所有操作都正常执行时,整个事务才会提交到数据库。1.事务是一组SQL语句的执行。要么全部成功,要么全部失败。不允许部分成功和失败。原子操作2.事务中的所有数据都被成功执行,

数据库事务( 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表示事务自动提交(默认是自动提交)

事务与锁第1张
set @@autocommit = 0;
设置事务提交的方法:0 表示事务是手动提交,1表示事务自动提交
事务与锁第2张
begin:开启事务
commit:提交一个事务
rollback:回滚事务到初始状态;
 事务与锁第3张

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

 事务与锁第4张

savapoint  t1;设置一个保存点为t1的位置
rollback to t1; 回滚到t1的保存点
关于存储引擎的其他知识见文章→→   索引及底层原理
MYSQL不同的存储引擎有哪些区别时?以下几点回答
----------------------------------------------------------------------
种类  |  锁机制  | B-树索引 | 哈希索引  |外键  |事务   | 索引缓存  | 数据缓存
----------------------------------------------------------------------
MYISAM| 表锁    |   支持   |  不支持  |不支持 |不支持 |  支持     | 不支持
----------------------------------------------------------------------
INNODB| 行锁    |   支持   |  不支持  |支持   |支持  |   支持    |  支持
----------------------------------------------------------------------
memory| 表锁    |   支持   |  支持    |不支持 | 不支持|   支持    | 支持
----------------------------------------------------------------------
 存储引擎涉及到的命令:
show engines;
数据库支持的存储引擎:
mysql> show enginesG;
*************************** 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

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

如果对整个MySQL的存储引擎做修改,直接修改配置文件
window 中是my.ini  在Linux系统中是my.cof
D:mysqlmysql-5.7.24-winx64(我自己电脑的存储位置)
 
事务与锁第6张
 
锁:表锁,行锁,共享锁,排它锁,死锁
MyISAM表锁:
MYISAM存储存储引擎支持表锁,不支持事务处理,不支持外键
MYISAM并发比较简单,只支持表锁粒度,锁的粒度比较大
并发能力,但是不会引起死锁,它支持表共享的读锁和表互斥的写锁
对MYISAM表的读操作,不会阻塞其他用户对同一张表的读操作,但是会阻塞其他用户
对同一张表的写操作
对MYISAM表的写操作,则会阻塞其他用户对同一个表的读和写操作
MYISAM的读与写之间互斥,写与写之间互斥,读与读之间共享

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

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

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

 

免责声明:文章转载自《事务与锁》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇linux上TCP和UDP测试延迟的方法执行sparksql出现OOM问题下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

【MySQL 组复制】1.组复制技术简介

组复制有两种模式 单主模式(single-primary/single-master)下自动选举出一个主节点,从而只允许在同一时刻只有该主节点可以更新数据。 对于MySQL的高级使用人员,可以通过复制组实现多主模型(multi-primary),这种模型下,所有的主节点都可以在同一时刻接受更新操作,即并发写。 MySQL组复制有一个内置的组成员服务(gro...

大数据量下高并发同步的讲解

对于我们开发的网站,如果网站的访问量非常大的话,那么我们就需要考虑相关的并发访问问题了。而并发问题是绝大部分的程序员头疼的问题, 但话又说回来了,既然逃避不掉,那我们就坦然面对吧~今天就让我们一起来研究一下常见的并发和同步吧。 为了更好的理解并发和同步,我们需要先明白两个重要的概念:同步和异步 1、同步和异步的区别和联系 所谓同步,可以理解为在执行完一个函...

SQL Server2000中死锁经验总结

将死锁减至最少 虽然不能完全避免死锁,但可以使死锁的数量减至最少。将死锁减至最少可以增加事务的吞吐量并减少系统开销,因为只有很少的事务: 回滚,而回滚会取消事务执行的所有工作。 由于死锁时回滚而由应用程序重新提交。 下列方法有助于最大限度地降低死锁: 按同一顺序访问对象。 避免事务中的用户交互。 保持事务简短并在一个批处理中。 使用低隔离级别。...

【转修正】sql server行版本控制的隔离级别

在SQL Server标准的已提交读(READ COMMITTED)隔离级别下,一个读操作会和一个写操作相互阻塞。未提交读(READ UNCOMMITTED)虽然不会有这种阻塞,但是读操作可能会读到脏数据,这是大部分用户不能接受的。有些关系型数据库(例如Oracle)使用的是另一种处理方式。在任何一个修改之前,先对修改前的版本做一个复制[WX1],后续的一...

单点突破:MySQL之日志

前言 开发环境:MySQL5.7.31 日志是 mysql 数据库的重要组成部分,记录着数据库运行期间各种状态信息。若数据库发生故障,可通过不同日志记录恢复数据库的原来数据。因此实际上日志系统直接决定着MySQL运行的鲁棒性和稳健性。MySQL中有六种日志文件,分别是:重做日志(redo log)、回滚日志(undo log)、二进制日志(binlog)、...

为什么完整备份不能截断事务日志

导言 完整备份不能截断事务日志,这是所有SQL Server DBA的一个常识, 为此,当数据库处于完整恢复模式时(非特别说明,下文所提到都是完整恢复模式下的数据库),DBA们必须频繁地使用事务日志备份的方式来防止日志文件变得过大。 这几乎成为了DBA们的一个定理,但,作为一个DBA,你证明过这个定理吗?你知道为什么完整备份不能截断事务日志吗? 一个错误的...