资讯专栏INFORMATION COLUMN

数据库之事务与并发控制

aaron / 1711人阅读

摘要:悲观锁非常影响并发性能,所以谨慎使用乐观锁假定当前事务操纵数据资源时,不会有其他事务同时访问该数据资源,乐观锁使用由程序逻辑控制的技术来避免可能出现的并发问题。读取出数据时,将此版本号一同读出,之后更新时,对此版本号加一。

一.事务的特性(ACID)

1.原子性:单个或多个操作为一个整体,要么全执行,要么全不执行(回滚)
2.一致性:事务执行是从一个一致性状态转为另一个一致性状态
3.隔离性:一个事务在提交前对数据的修改对于其它事务不可见
4.持久性:事务一旦提交对数据的改变是永久的

二.并发事务可能导致的问题

1.丢失数据修改 (修改的数据被其它线程事务覆盖)
2.脏读(B事务读取了A事务尚未提交的数据,且A事务回滚数据)
3.不可重复读(一个事务中两次读取的数据内容不一致,重点在update)
4.幻读(一个事务中两次读取的数据量不一致,重点在insert,delete)

三.事务并发访问问题的解决方式 1.锁

1.1 共享锁和排他锁

(1)共享锁(S锁,读锁):本事务只可进行读操作,其它事务加S锁也可读
(2)排他锁(x锁,写锁):本事务可进行读写,不允许其它事务加锁和操作
(3)更新所(u锁):防止通常形式的死锁,两个拥有共享锁的事务要同时更新数据时,需要将共享锁转换为排他锁,所以他们都需要X锁并且要等待对方释放s锁(x锁和其它事务的S锁不兼容),会发生死锁

1.2 临时锁与持续锁

 锁的时效性,指明加锁生效期是当前语句结束还是当前事务结束

1.3表级锁和行级锁

 锁的粒度,指明加锁的对象是当前表还是当前行
 

1.4乐观锁和悲观锁
这两种锁的说法,主要是对“是否真正在数据库层面加锁”进行讨论。
(1)悲观锁:悲观锁假定当前事务操纵数据资源时,肯定还会有其他事务同时访问该数据资源,为了避免当前事务操作受到影响,悲观锁需使用数据库的锁机制实现。java中的synchronized锁就是悲观锁。悲观锁非常影响并发性能,所以谨慎使用
(2)乐观锁假定当前事务操纵数据资源时,不会有其他事务同时访问该数据资源,乐观锁使用由程序逻辑控制的技术来避免可能出现的并发问题。最常用的方式是基于数据版本记录机制实现(一般是通过为数据库表增加一个 “version” 字段来实现。读取出数据时,将此版本号一同读出,之后更新时,对此版本号加一。此时,将提交数据的版本数据与数据库表对应记录的当前版本信息进行比对,如果提交的数据版本号大于数据库表当前版本号,则予以更新,否则认为是过期数据)所以不能避免脏读问题

2.设置事务的隔离级别
(1) 读未提交:事务写阻塞其它事务的写不阻塞读(加“持续-X锁”实现)
      ---避免丢失数据修改
      
(2)读已提交:事务写会阻塞其它事务的读和写(写操作加“持续-X”锁,读操作加“临时-S锁”实现)
     ---避免丢失数据修改和脏读
     
(3)可重复读:事务读会阻塞其它事务的写,不会阻塞读,事务写会阻塞其它事务读写(写操作加“持续-X”锁,读操作加“持续-S锁”实现)    
     ---避免丢失数据修改和脏读和不可重复读幻读
     
(4)串行化:事务的最高级别,在每个读的数据行上,加上锁,使之不可能相互冲突,因此,会导致大量的超时现象
    ---解决了所有问题
   

3.三级加锁协议
   (1)一级加锁协议:读数据不加锁,修改数据前加X锁(解决丢失数据修改)
   (2)二级加锁协议:读取时加s锁,修改时加x锁(解决丢失数据修改+脏读)
   (3)三级枷锁协议:全程加x锁和s锁(解决所有问题)

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/17748.html

相关文章

  • 关于MySQL的知识点面试常见问题都在这里

    摘要:但是这将严重影响程序的性能。垂直分区的优点在于可以使得行数据变小,在查询时减少读取的数,减少次数。此外,垂直分区可以简化表的结构,易于维护。垂直分区的缺点在于主键会出现冗余,需要管理冗余列,并会引起操作,可以通过在应用层进行来解决。 Java面试通关手册(Java学习指南,欢迎Star,会一直完善下去,欢迎建议和指导):https://github.com/Snailclimb/Jav...

    LeoHsiun 评论0 收藏0
  • 深入解析 PostgreSQL 系列并发控制事务机制

    摘要:深入解析系列之并发控制与事务机制并发控制旨在针对数据库中对事务并行的场景,保证中的一致性与隔离。启动并执行第一个命令。事务管理器分配,并返回事务快照,因为正在进行中。意味着该行由另一个并发事务更新,并且其事务尚未终止。 showImg(https://segmentfault.com/img/remote/1460000018081793); 深入解析 PostgreSQL 系列整理...

    JohnLui 评论0 收藏0

发表评论

0条评论

aaron

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<