美文网首页
数据库内部锁事务和显式外部锁

数据库内部锁事务和显式外部锁

作者: 賈小強 | 来源:发表于2019-02-28 21:45 被阅读0次

简书 賈小強
转载请注明原创出处,谢谢!

情况1:事务a往表X写入1 2 3

由于事务的原子性,要么成功要么失败,所以要么写入1 2 3,要么一个也没有写入

情况2:事务a往表X写入1 2 3,同时事务b进行相同操作

由于事务的隔离性,事务a和事务b互相独立

情况3:事务a往表X写入1 2 3,同时事务b往表Y写入 1 2 3

不论是对同一张表还是同一个数据库的两张表操作,事务的隔离性体现在事务,所以并不会出现所谓的事务a提交了,然后影响事务b的情况

情况4:事务a查找表X没有1则写入1,同时事务b进行相同操作
  • 悲剧:事务a查找发现没有,于是打算写入,事务b在a事务提交前查找也发现没有,于是也认为应该写入,最后都写入导致重复写问题

  • 分析:数据库有两种内部锁:单个SQL语句比如select和insert而言,对于select为读锁,这种锁允许多个事务同时查询一张表,对于insert为写锁,这种锁只允许同一时间只有一个事务能够操作,由于select是幂等的,而insert是原子性的,也就说可以认为单条SQL语句是原子性的,但是select...insert形式两个SQL语句的组合,数据库自身并没有维护其原子性,这在并发的时候很容易出现重复写问题,对于select...update则是丢失修改问题

  • 解决方式:

    1. 采用select...for update,比如Oracle数据库提供了这种形式的语句,在某个事务执行这条SQL语句的时候将阻塞其它事务,所以是安全的,不过由于是悲观锁会阻塞其他所有事务,所以可能导致性能问题
    2. 采用redis显式构造一个悲观锁,其效果和方式一的一样,安全但是效率不高,相比方式一优点是可以将多个SQL语句写在一个锁之间
    3. 可以换一个角度改进设计方案,避免这种需要悲观锁的方式
    4. 改用redis中形式的乐观锁,并发的时候都可以修改,谁先修改成功就算谁的,其他同时修改的发现提交时已经被别的修改了则回退,乐观锁的优点就是让耗时少的先通过,不过并不是所有情况都适合乐观锁,在竞争激烈的情况下可能导致很多的无效尝试
  • 结论:select...insert操作需要加锁同步

情况5:事务a查找表X没有1写入1,查找表Y没有2写入2,同时事务b进行相同操作
  • 问题:通过select...for insert或者显式悲观锁给每个表的select...insert加悲观锁,期望缩小锁导致的同步代码范围,提升程序并发效率,是否没问题?
  • 悲剧:虽然保证了对某张表的select...insert原子性,但比如事务a查找表X没有1写入1,然后对表Y处理,但是事务还没提交,而事务b在事务a释放表X锁后,获取到表X的锁可以操作表X,进行查找表X没有1写入1的操作,同样导致了重复写问题,或者可能事务a现提交成功写入了id=1的数据,到事务b的时候提交结果发现有的id=1的已经存在了,导致违反数据库完整性约束
  • 结论:如果打算对一系列表的select...insert操作看作一个整体事务,那么应该对整个事务加一个显式外部悲观锁,只有这一系列表并不需要看作一个整体事务,那么才可以增多锁和事务,达到减少同步代码的目的,但是锁和事务总是维持同范围的

Happy learning !!

相关文章

  • 数据库内部锁事务和显式外部锁

    简书 賈小強转载请注明原创出处,谢谢! 情况1:事务a往表X写入1 2 3 由于事务的原子性,要么成功要么失败,所...

  • 从 synchronized 到 CAS 和 AQS - 彻底弄

    Java 中的并发锁大致分为隐式锁和显式锁两种。隐式锁就是我们最常使用的 synchronized 关键字,显式锁...

  • JDK并发包之重入锁

    锁:对共享数据加锁使其变为临界区。(排它锁)与共享锁 锁有内部锁(synchronized关键字修饰的)与显式锁(...

  • 并发编程反模式

    不连贯的同步性: 为了同步某个对象或者对象本身的某个域的访问,使用同步锁(内部锁或者显式锁,例如,对象本身的内部锁...

  • 05.锁机制和条件对象简述

    Java的锁机制主要分内置锁(隐式锁)和显式锁。 内置锁 Java每个对象都有一个内置的锁对象,这些锁对象不需要显...

  • 线程安全,内存可见性,竞态条件,内置锁,显式锁概述

    线程安全,内存可见性,竞态条件,内置锁,显式锁概述 在Java中按照锁的实现方式可以划分为内置锁和显式锁,内置锁有...

  • 分布式锁及分布式事务

    分布式锁是解决并发时资源争抢的问题,分布式事务和本地事务是解决流程化提交问题。一、其中分布式锁实现:1.基于数据库...

  • 两端锁协议

    1、数据库锁 数据库锁粒度划分:行锁、页锁、表锁。共享锁:读锁、S锁。事务T可以对A进行读取,其他事务只能读取而不...

  • Java多线程编程知识点系统梳理(3)

    一、锁的概述 (1)内部锁:synchronized关键字,通过指定对象作为监视对象(2)显式锁:Lock接口,R...

  • 14. 并发终结之ReentrantLock

    显式锁Lock是JDK1.5开始引入的排他锁,作用跟内部锁一致,只是提供了一些内部锁所不具备的特性。Reentra...

网友评论

      本文标题:数据库内部锁事务和显式外部锁

      本文链接:https://www.haomeiwen.com/subject/ogvhuqtx.html