• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • MsSql
  • Mysql
  • oracle
  • MariaDB
  • DB2
  • SQLite
  • PostgreSQL
  • MongoDB
  • Redis
  • Access
  • 数据库其它
  • sybase
  • HBase
您的位置:首页 > 数据库 >Mysql > 数据库中的事务和并发问题的实例讲解

数据库中的事务和并发问题的实例讲解

作者:匿名 字体:[增加 减小] 来源:互联网 时间:2018-12-05

匿名通过本文主要向大家介绍了数据库,题的,发问等相关知识,希望本文的分享对您有所帮助
数据库中的事务和并发问题探讨

引子

最近有同事写了段代码,负责创建订单的逻辑,代码审查时发现可能会有并发的问题。同事并不认同,他认为他的逻辑是写在存储过程中的,应该没有问题。

代码的逻辑大概是(伪代码):

begin transaction

if 查询到客户存在进行中的订单
 rollback transaction

if 查询到设备存在进行中的订单
 rollback transaction

插入订单

commit transaction

下面针对这个逻辑进行分析,为什么这个事务会出现并发问题。

事务概述

首先,提出两个问题,然后带着问题讨论事务相关的知识点,最后来解决这两个问题并回答前文的问题。

第一个问题,事务是否可以并发?

第二个问题,数据库是怎么隔离事务的?

事务的表现特性

数据库中执行事务涉及到很多方面,包括如何处理临界资源,如何加锁解锁等等。但是无论事务如何执行,都需要保证以下几个特性:

  • 原子性

  • 一致性

  • 隔离性

  • 持久性

  • 原子性:所有的操作是一个逻辑单元,要么都提交成功,要么就都失败;

    一致性:只有合法的数据被写入数据库,否则事务回滚到最初的状态;

    隔离性:允许多个事务同时进行,而不会破坏数据的正确性和完整性;

    持久性:事务结束后,已经提交的结果被固化保存。

    数据库的各种锁

    1. 共享锁

    共享锁用于非独占的业务,允许多个事务同时读取锁定的资源,但是不允许资源被更新。

  • 加锁时机:执行select语句时默认会被加上

  • 解锁时机:执行完读取后默认解除

  • 与其他锁兼容性:数据上被设置了共享锁,则不会允许再增加共享锁和独占锁

  • 并发性能:具有良好的并发性能

    1. 排他锁

    排他锁,也叫独占锁。顾名思义,被排他锁锁定的资源不会允许其他事务进行任何操作。

  • 加锁时机:执行insert,update,delete时默认会被加上

  • 解锁时机:事务结束才能解除

  • 兼容性:如果数据上有其他锁,不能增加独占锁;同样独占锁存在时也不会允许增加其他锁

  • 并发性能:其他事务必须等待前一个事务结束后才能执行,不能并发,只能串行

    1. 更新锁

    在更新的初始阶段用于锁定所需要的资源,防止在读取阶段使用共享锁造成死锁。

  • 加锁时机:执行update时,使用更新锁锁定相关资源

  • 解锁时机:读取完毕,执行更新操作时,更新锁升级为独占锁

  • 兼容性:更新锁与共享锁兼容,即可以同时存在更新锁和共享锁,但只能有一个更新锁

  • 并发性能:更新初期的读取阶段可以允许其他事务读取资源,允许有限的并发;后期对资源进行独占时不允许并发。

  • 事务隔离级别

    通用的事务隔离级别有四种,SQL Server还有另外扩展出来的级别,在此不多介绍。

    1. Serializable(串行化)

    工作方式类似于可重复读。但它不仅会锁定受影响的数据,还会锁定这个范围。这就阻止了新数据插入查询所涉及的范围,这种情况可以导致幻像读。

    1. Repeatable Read(可重复读)

    像已提交读级别那样读数据,但会保持共享锁直到事务结束。

    1. Read Commit

    只读取提交的数据并等待其他事务释放排他锁。读数据的共享锁在读操作完成后立即释放。已提交读是SQL Server的默认隔离级别。

    1. Read Uncommited

    在读数据时不会检查或使用任何锁。因此,在这种隔离级别中可能读取到没有提交的数据。

    回答前文的问题

    第一个问题,事务是否可以并发?

    答案是肯定的,数据库中为了提高性能,允许同时进行多个事务操作,这个事务跟发起方式无关,使用存储过程发起,或者使用代码发起,又或者使用普通的SQL语句发起并没有什么区别。

    第二个问题,数据库是怎么隔离事务的?

    要回答这个问题,先要理解数据库中的锁机制和数据库事务隔离级别。数据库中的锁可以分为三种类型:共享锁、独占锁和更新锁。使用不同级别的锁并配合不同的锁定范围已达到不同的事务隔离级别并在此基础上并发或串行执行事务。

    第三个问题,为什么本文开头的事务会存在并发问题?

    因为事务的开始执行的是select,select使用的是共享锁,有可能并发的事务在同一时间执行select导致同时认为自己都是合法操作,而排队执行后续的事务。结果导致了实际上就有可能插入重复的数据,比如只剩下一个商品,却创建了两个销售订单。

    如何防止并发问题

    1. 在事务中

    根据前文所讲,使用insert,update或delete可以在默认事务级别人为造成事务串行化,因此可以在事务内部一开始都使用update更新一条公共的数据,这样的话同类型的事务都会串行化,然后再增加一个判断语句,用于判断后续的事务内容是否应该执行。这样足以确保所有的操作都按照合理合法,唯一的缺点是可能造成性能问题。

    1. 在事务外

    现在分布式的系统越来越多,但是再分布的系统也会有些共享资源,比如redis或zookeeper,可以利用redis或者zookeeper造一些分布式的锁(此类属于其他博文内容,在此不再展开)。利用事务外部的锁将同类型的事务做一些串行化处理,再配合事务内部的检查机制,足以确保解决事务的并发问题。

    参考资料

  • 事务并发的问题及处理

  • 数据库事务的四大特性以及事务的隔离级别

  • 数据库事务和并发

  • SQLServer事务的隔离级别

以上就是数据库中的事务和并发问题的实例讲解的详细内容,更多请关注微课江湖其它相关文章!

分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • 解析mysql中如何获得数据库的大小
  • 解析mysql修改为utf8后仍然有乱码的问题
  • 5个常用的MySQL数据库管理工具详细介绍
  • 解析远程连接管理其他机器上的MYSQL数据库
  • 解析mysql 缓存如何使用内存
  • 浅析mysql 语句的调度优先级及改变
  • 关于mysql 的时间类型选择
  • 基于mysql体系结构的深入解析
  • 解析mysqldump的delay-insert选项
  • 优化mysql数据库的经验总结

相关文章

  • 2017-05-11mysql计算时间差函数
  • 2018-12-05第一章 python入门
  • 2018-12-05中小软件公司项目管理(3.3 项目外部关键成功因素)
  • 2018-12-05Mysql如何配置及Mysql服务无法启动
  • 2018-12-05mysql下为数据库设置交叉权限的方法实例详解
  • 2018-12-05SQL的模糊查询实例讲解
  • 2017-05-11innodb 库的备份注意点(由phpmyadmin引起的解决方案)
  • 2018-12-05Windows10下mysql5.5数据库命令行中文乱码解决方案
  • 2018-12-05SQL语句练习实例之七 剔除不需要的记录行
  • 2018-12-05sql json 简单介绍

文章分类

  • MsSql
  • Mysql
  • oracle
  • MariaDB
  • DB2
  • SQLite
  • PostgreSQL
  • MongoDB
  • Redis
  • Access
  • 数据库其它
  • sybase
  • HBase

最近更新的内容

    • 检查并修复mysql数据库表的具体方法
    • 在VB.NET应用中使用MySQL的方法
    • docker安装mysql的简单实例
    • sql server 常用的几个数据类型
    • MySQL文件系统先睹为快(1)
    • mysql下普通用户备份数据库时无lock tables权限的解决方法
    • MySQL数据库中删除重复记录的方法总结[推荐]
    • 5分钟读懂MySQL字符集设置
    • mysql中为用户设置密码的多种方法
    • MySQL的PHP 语法

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有