[数据库]事务与隔离级别

事务概述

redo log概述

undo log概述

事务控制语句

配置参数

控制语句

事务隔离级别

隔离级别简介

MVCC并发控制

锁类型简介


事务概述

事务是作为单个逻辑操作单元的一系列操作。事务可以包含一条或多条sql语句,所有的语句被当做一个操作单元,要么全部成功、要么全部失败(即作为一个原子操作)。

数据库中的事务要满足ACID特性:

  • Atomicity:原子性,整个事务要么全部执行成功,要么全部执行失败;
  • Consistency:一致性,数据库总是从一个一致性状态转为另外一个一致性状态,不存在中间状态;
  • Isolation:隔离性,事务在提交之前所做的修改能否为其他事务可见;针对不同的隔离性,有不同的隔离级别;
  • Durability:持久性,事务一旦提交,所做出的修改将永久有效(即修改不会丢失);
    在MySQL中,事务是通过‘事务日志’来实现,具体可分为‘redo log’和‘undo log’。

redo log概述

MySQL在执行事务时,先将事务中的sql语句涉及到的所有数据库操作记录到‘redo log’中,然后将操作同步到数据库文件中(在实际修改数据库前,先把操作记录到日志中)。这样即使数据修改到一半被打断(如当机等),也能通过日志将剩余的操作同步到数据库中。

redo能够实现原子性(A),保证一个事务中所有sql被当成一个执行单元。‘redo log’是物理日志,其中记录的是数据库对页的操作,而非逻辑上的增删改查;因此重做日志具有幂等性。

‘redo log’由两部分组成:

  • ‘redo log buffer’(重做日志缓冲区):存放在内存中
  • ‘redo log file’(重做日志文件):存放在硬盘上,为一段连续的空间,以加快读写速度。

多个日志记录文件组成一个log group(重做日志组),当组中的第一个logfile被写满时,就写下一个;当组内的所有logfile都写满时,就重新从第一个logfile写(覆盖原来的)。为了保证进一步的安全,日志可存储在raid1等冗余设备上。

undo log概述

‘undo log’可看成数据修改前的备份。若事务执行过程中,有一条sql无法成功执行,需要进行回滚时,就需要根据‘undo log’进行撤销,将所有修改过的数据从逻辑上恢复到事务开始前的样子。

‘undo log’是逻辑日志,若前面inert 10条记录,则undo时即delete 10条;因此不具有幂等性。


事务控制语句

配置参数

MySql中(innodb引擎时),通过show global variables like 'innodb%log%'查看与日志相关的配置参数:

  • innodb_log_file_size:redo log file文件的大小;
  • innodb_log_files_in_group:重做日志组中的有多少个redo log file;
  • innodb_log_group_home_dir:日志组文件所在路径;
  • innodb_mirrored_log_groups:日志组镜像的数量(没有镜像时为1);
  • innodb_flush_log_at_trx_commit:事务提交以后,是否立即将redo从内存中刷到磁盘中。
    • 1(默认):事务提交时刷到磁盘上;事务提交->log buffer->OS buffer->log file
    • 0:提交时并不会刷到磁盘,但会每秒自动刷一次;
    • 2:提交时,只会写入到系统内存(OS buffer)中,每秒从系统缓存中刷到磁盘中;

控制语句

默认情况时,事务是自动提交的(执行sql语句后,自动执行commit):
show global variable like 'autocommit%'
show session variable like 'autocommit%'

可通过控制语句,显式地控制事务:

  • start transaction / begin:显式地开始一个事务(存储过程中要使用start transaction,避免与begin…end混淆);
  • commit / commit work:提交事务;
  • rollback / rollback work:回滚事务,撤销所有未提交的修改,并结束当前事务;
  • savepoint标识符:创建一个事务保存点,以便回滚到当前点(而非回滚整个事务);
  • rollback to savepoint-标识符:回滚到指定保存点;
  • release savepoint-标识符:删除一个保存点;

事务隔离级别

对于MySQL服务器,可以有若干个客户端与其连接(每个连接称为一个会话Session)。不同的会话可以同时发送各种请求(事务),为了避免事务之间互相影响,并提高系统的并发处理能力,提出了各种隔离级别。

隔离级别简介

事务通过锁机制满足隔离性,事务的隔离级别决定了事务间的隔离性:

  • READ-UNCOMMITED:读未提交,能看到其他事务中未提交的修改(即脏读);
  • READ-COMMITTED:读提交,只要其他事务提交了,在当前事务中即可见;会出现‘不可重读’(两次读取的同一条目的内容可能不同)和‘幻读’(两次读取的条目数可能不同,多出或少了)问题;
  • REPEATABLE-READ(默认):可重复读,事务中对同一条记录看到的内容始终相同(在事务中,即使前后两条查询之间,其他事务对数据做了修改,读取到的内容不会改变);会出现‘幻读’问题;
  • SERIALIZABLE:串行化,做完一个事务再做其他事务,写事务会阻塞所有读事务;因此也就失去了并发能力。

show variable like 'tx_isolation'可查看设置的隔离级别,my.cnf配置文件中设定transaction_isolation=REPEATABLE-READ

innodb中采用一致性非锁定读机制(‘可重读’和‘读提交’隔离级别下)提高数据库并发性:读取数据时(使用非锁定读),若当前行被施加了排他锁,则不会等待锁释放,而是去读取一个快照数据。
因此会引起幻读现象:即同一个事务中,前后两条查询语句看到的数据可能不同(多出、或减少条目)。

隔离级别越高,隔离性越强,遇到的问题越少,并发越弱:

标题脏读不可重读幻读
读未提交
读提交×
可重读××
串行化×××

MVCC并发控制

MVCC(Multi-Version Concurrency Control)多版本并发控制,用于‘可重复读’和‘读已提交’隔离级别的处理。通过保存数据库某个时间的快照,来实现的。

  • 每行数据都存在一个版本,每次数据更新时更新该版本;
  • 修改时复制(Copy)出当前版本随意修改,保证事务间无干扰;
  • 保存时比较版本号,成功再覆盖原记录,失败则放弃;

每一行数据保存两个隐藏的列:当前行创建时的版本号和删除时的版本号(未删除时为空)。版本号为系统的版本号,新事务开始时自动递增(事务开始时系统版本号为事务的版本号)。

增删改查时的版本号处理
插入数据时(事务版本设为1):记录的版本号为当前事务的版本号

idnamecreate-versiondelete-version
1oldname1 

更新数据时(事务版本设为2):先标记旧的数据为已删除(删除版本号为当前事务版本号),然后插入一条新的记录(更新后的数据);

idnamecreate-versiondelete-version
1oldname12
1new-name2 

删除数据时(事务版本设为3):删除版本号记为当前事务版本号

idnamecreate-versiondelete-version
1new-name23

查询操作:只有符合条件的记录才会被查询出来

  • 删除版本号未指定(空)或大于当前版本号,即事务开始时未删除的行;
  • 创建版本号小于或等于当前版本号,即当前事务或之前已插入(或修改)的行;

锁类型简介

为保证数据访问的一致性、有效性,就需要锁;同时锁冲突也是影响数据库并发性能的一个重要因素:

  • 表级锁:访问数据库时,锁定整表数据;开销小,加锁快;锁的粒度大,冲突概率高,并发度低;
  • 行级锁:访问数据库时,锁定整行数据;开销大,加锁慢;会出现死锁,锁粒度小,冲突概率低,并发度高;
  • 页锁:访问数据库时,锁定一页数据;介于前两者之间;会出现死锁,并发度一般;

数据库的增删改操作默认都会加排他锁,而查询不会加任何锁。

  • 共享锁(悲观锁的一种):对某一资源加共享锁,自身可以读该资源,其他人也可以读该资源(也可以再继续加共享锁,即多个共享锁可共存),但无法修改。要想修改就必须等所有共享锁都释放完之后。
  • 排他锁:对某一资源加排他锁,自身可以进行增删改查,其他人无法进行任何操作。

悲观锁与乐观锁是两种常见的资源并发锁设计思路。通常所说的“一锁二查三更新”即使用的是悲观锁。

  • 悲观锁:先获取锁,再进行业务操作。每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这时别人想拿这个数据就会阻塞等待。
  • 乐观锁:先进行业务操作,不到万不得已不去拿锁。每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。

乐观锁在不发生取锁失败的情况下开销比悲观锁小,但是一旦发生失败回滚开销则比较大,因此乐观锁适用于写比较少的情况下,即冲突真的很少发生的时候,这样可以省去了锁的开销,加大了系统的整个吞吐量。经常产生冲突,上层需要不断重试情况,乐观锁反倒是降低了性能,这种情况下用悲观锁就比较合适。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
系统根据B/S,即所谓的电脑浏览器/网络服务器方式,运用Java技术性,挑选MySQL作为后台系统。系统主要包含对客服聊天管理、字典表管理、公告信息管理、金融工具管理、金融工具收藏管理、金融工具银行卡管理、借款管理、理财产品管理、理财产品收藏管理、理财产品银行卡管理、理财银行卡信息管理、银行卡管理、存款管理、银行卡记录管理、取款管理、转账管理、用户管理、员工管理等功能模块。 文中重点介绍了银行管理的专业技术发展背景和发展状况,随后遵照软件传统式研发流程,最先挑选适用思维和语言软件开发平台,依据需求分析报告模块和设计数据库结构,再根据系统功能模块的设计制作系统功能模块图、流程表和E-R图。随后设计架构以及编写代码,并实现系统能模块。最终基本完成系统检测和功能测试。结果显示,该系统能够实现所需要的作用,工作状态没有明显缺陷。 系统登录功能是程序必不可少的功能,在登录页面必填的数据有两项,一项就是账号,另一项数据就是密码,当管理员正确填写并提交这二者数据之后,管理员就可以进入系统后台功能操作区。进入银行卡列表,管理员可以进行查看列表、模糊搜索以及相关维护等操作。用户进入系统可以查看公告和模糊搜索公告信息、也可以进行公告维护操作。理财产品管理页面,管理员可以进行查看列表、模糊搜索以及相关维护等操作。产品类型管理页面,此页面提供给管理员的功能有:新增产品类型,修改产品类型,删除产品类型。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值