数据库的加锁操作_数据库加锁的方法-程序员宅基地

技术标签: 高并发  数据库加锁  mysql  thinkphp  mysql锁机制  thinkphp加锁  

数据库的加锁操作

从事一个项目,需要考虑数据的安全性,之前对于数据库这部分的数据操作学习的比较零散,由于手头的项目,于是系统的学习一个知识,我们大致都会经历这么几个过程(what this ? why to use ? how to use?),首先,我们需要搞懂,下面几个知识点:

一: 什么是数据库加锁 ?

数据库加锁: 简单的意思就是对于在执行一个操作(比如修改)时,对这个操作的对象加锁,放置其他操作读取到脏数据或者幽灵数据。

或者术语来说就是一种排他锁,当写的时候不允许其他程序写,这样就可以保证数据一致性了

二:为什么要给数据加锁?

对于这点,我们需要简单的了解几个概念:

(1).什么是事务?

事务: 是用户定义的数据库操作系列,这些操作作为一个完整的工作单元执行。一个事务内的所有语句作为一个整体。要么全部执行,要么全部不执行。
事务的几个特点: 原子性,一致性,隔离性,持久性, 简称ACID特征

一般来讲: 事务的这几个特点被遭到破坏的有下列几个情况:
(1) 多事务并行运行时,不同事务的操作有交叉情况。(->_-> 如果你想不到列子:就想想多线程问题)
(2) 事务在运行过程中被强迫停止。

(2)什么是脏读:

脏读 :脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。

(3)什么是不可重复读?

不可重复读 :是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。例如,一个编辑人员两次读取同一文档,但在两次读取之间,作者重写了该文档。当编辑人员第二次读取文档时,文档已更改。原始读取不可重复。如果只有在作者全部完成编写后编辑人员才可以读取文档,则可以避免该问题。

(4)什么是幻读?

幻读 : 是指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样。例如,一个编辑人员更改作者提交的文档,但当生产部门将其更改内容合并到该文档的主复本时,发现作者已将未编辑的新材料添加到该文档中。如果在编辑人员和生产部门完成对原始文档的处理之前,任何人都不能将新材料添加到文档中,则可以避免该问题。

因为在上述的情况下,数据会出现脏数据。对于一个考虑安全性的系统而言,加锁自然是十分必要.

三、如何对数据加锁:

对于数据加锁: 一般分为如下两种,第一类,就是数据库自己加锁,第二类,就是线程锁。
第一种: 数据库自己加锁
对于锁的级别: 库级锁,表级锁,页级锁,行级锁。(这篇文章提供了较多的说明)
http://blog.csdn.net/cspyb/article/details/1865538
举几个列子:对于数据表的加锁:
方法一: 使用SQL语句进行加锁

public void test() {  
    String sql = "lock tables Gxjun write";  
    // 或String sql = "lock tables Gxjun read";   
    // 如果想锁多个表 lock tables Gxjun read stu write , .....   
    String sql1 = "select * from Gxjun ";  
    String sql2 = "unlock tables";  
    try {  
        this.pstmt = conn.prepareStatement(sql);  
        this.pstmt1 = conn.prepareStatement(sql1);  
        this.pstmt2 = conn.prepareStatement(sql2);  
        pstmt.executeQuery();  
        pstmt1.executeQuery();  
        pstmt2.executeQuery();  
    } catch (Exception e) {  
        System.out.println("异常" + e.getMessage());  
    }  
}  

方法二 , 采用记录锁加锁:

public void test() {  
  
    String sql = "select * from Gxjun for update";   
   
    try {  
        conn.setAutoCommit(false);  
        this.pstmt = conn.prepareStatement(sql);  
        pstmt.executeQuery();  
  
    } catch (Exception e) {  
        System.out.println("异常" + e.getMessage());  
    }  
}  

1.for update 与 lock in share mode 属于行级锁和页级锁

2.for update 排它锁,lock in share mode 共享锁

3.对于记录锁.必须开启事务.

4.行级锁定事实上是索引记录的锁定.只要是用索引扫描的行(或没索引全表扫描的行),都将被锁住.

5.在不同的隔离级别下还会使用next-key locking算法.即所扫描的行之间的“间隙”也会也锁住(在Repeatable read和Serializable隔离级别下有间隙锁).

6.在mysql中共享锁的含义是:在被共享锁锁住的行,即使内容被修改且并没有提交.在另一个会话中依然看到最新修改的信息.

在同一会话中加上了共享锁.可以对这个表以及这个表以外的所有表进行增、删、改、查的操作.

在不同的会话中.可以查到共享锁锁住行的最新消息.但是在Read Uncommitted隔离级别下不能对锁住的表进行删,
改操作.(需要等待锁释放才能操作…)
在Read Committed隔离级别下不能对锁住的表进行删,改操作.(需要等待锁释放才能操作…)
在Repeatable read隔离级别下不能对锁住行进行增、删、改操作.(需要等待锁释放才能操作…)
在Serializable隔离级别下不能对锁住行进行增、删、改操作. (需要等待锁释放才能操作…)
7.在mysql中排他锁的含义是:在被排它锁锁住的行,内容修改并没提交,在另一个会话中不会看到最新修改的信息。
在不同的会话中.可以查到共享锁锁住行的最新消息.但是Read Uncommitted隔离级别下不能对锁住的表进行删,
改操作.(需要等待锁释放才能操作…)
在Read Committed隔离级别下不能对锁住的表进行删,改操作.(需要等待锁释放才能操作…)
在Repeatable read隔离级别下不能对锁住行进行增、删、改操作.(需要等待锁释放才能操作…)
在Serializable隔离级别下不能对锁住行进行增、删、改操作. (需要等待锁释放才能操作…)

8.在同一个会话中的可以叠加多个共享锁和排他锁.在多个会话中,需要等待锁的释放.

9.SQL中的update 与 for update是一样的原理.

10.等待超时的参数设置:innodb_lock_wait_timeout=50 (单位秒).

11.任何可以触发事务提交的命令,都可以关闭共享锁和排它锁.

四、thinkphp加锁操作:

$result = $model ->lock(lock:true)->where($where)->find();
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_43687896/article/details/84069654

智能推荐

代码质量度量标准_SSIM全攻略:理论+代码(PyTorch)-程序员宅基地

文章浏览阅读759次。作者:Pranjal Datta编译:ronghuaiyang导读有很多资料解释了SSIM背后的理论,但很少有资源深入研究细节,本文就是试图填补这一空白的谦虚尝试。最近,在实现一篇深度估计论文时,我遇到了术语结构相似性指数(SSIM)。SSIM作为度量两个给定图像之间相似度的度量指标。由于这项技术从2004年就开始了,有很多资料解释了SSIM背后的理论,但很少有资源深入研究细节,这对于基于梯度的实..._ssim指标的亮度计算是怎么定义的

java求数列的最大子段和_[剑指offer题解][Java]连续子数组的最大和-程序员宅基地

文章浏览阅读165次。前言众所周知,《剑指offer》是一本“好书”。如果你是个算法菜鸡(和我一样),那么最推荐的是先把剑指offer的题目搞明白。对于剑指offer题解这个系列,我的写作思路是,对于看过文章的读者,能够做到:迅速了解该题常见解答思路(偏门思路不包括在内,节省大家时间,实在有研究需求的人可以查阅其它资料)思路尽量贴近原书(例如书中提到的面试官经常会要求不改变原数组,或者有空间限制等,尽量体现在代码中,保..._请编写程序求数列的最大子段和。提示:输入一组整型数据,输出最大子段和。

如何判断大小端字节序-程序员宅基地

文章浏览阅读688次。大端(存储)模式,是指数据的低位保存在内存的高地址中;小端(存储)模式,是指数据的高位保存在内存的低地址中。出现大小端模式的原因:计算机系统中,是以字节为单位的,每个地址单元都对应着一个字节,一个字节大小为8bit位。但是c语言中除了8bit的char类型以外,还有其他16bit或32bit的类型等等。此外,对于大于8位位数的处理器来说,由于寄存器的宽度大于一个字节,就会出现怎样安排多个字节的..._如何判断大小端字节序

【B/S】引用Google或微软的CDN加载jQuery_\b微软进入cdn美秋天的词-程序员宅基地

文章浏览阅读1.4k次。一、前言前文介绍了JQuery的基础知识,下面小编给大家介绍一下引用Google或微软的CDN加载jQuery。二、内容分析 在网页中我们经常使用jQuery库,选择使用的jQuery加载源,能有效加快网站的加载速度,目前最佳的选择就是使用Google或Microsoft提供的CDN jQuery源。Google Ajax API CDNhttp://ajax.googleapis.com_\b微软进入cdn美秋天的词

【UEFI实战】UEFI-Free-程序员宅基地

文章浏览阅读1.1k次,点赞2次,收藏2次。本文介绍那些非UEFI的x86启动器。_uefi-free

数据结构C(4)——循环链表、双向链表、双向链表的插入、删除_循环链表、双向链表中插入、删除结点的指针修改-程序员宅基地

文章浏览阅读606次。一、循环链表循环链表是一种头尾相接的链表(即:表中最后一个结点的指针域指向头结点,整个链表形成一个环)优点:从表中任一结点出发均可找到表中其他结点注意:由于循环链表中没有NULL指针,故涉及遍历操作时,其终止条件就不再像非循环链表那样判断p或p->next是否为空,而是判断他们是否等于头指针循环条件p!=NULL → p!=Lp->next!=NULL → p-&_循环链表、双向链表中插入、删除结点的指针修改

随便推点

Flink StreamingFileSink 文件到hdfs 文件一直处于inprogress状态无法生成正式文件_hdfs 文件 出现包含inprogress-程序员宅基地

文章浏览阅读6.9k次,点赞4次,收藏10次。问题描述:任务逻辑是通过实时读取Kafka数据,一分钟计算一次数据,并利用Flink StreamingFileSink将数据落地到HDFS文件中。为了应对大促剧增的数据量,对当前运行稳定的集群进行了扩容处理,任务重启后发现写入的hdfs文件一直处于inprogress状态无法滚动生成正式文件。解决过程:开始是猜想可能是并行度过多,导致产生大量临时文件,文件句柄太多,关闭耗时导致文件一直无法完成合并?将并行度调整到1,发现问题并没有解决。又猜想是因为调整了checkpoint参数,禁用掉che_hdfs 文件 出现包含inprogress

2021年06月 C/C++(四级)真题解析#中国电子学会#全国青少年软件编程等级考试_中国电子学会c++四级-程序员宅基地

文章浏览阅读259次。图1给出了一个数字三角形。从三角形的顶部到底部有很多条不同的路径。对于每条路径,把路径上面的数加起来可以得到一个和,你的任务就是找到最大的和。注意:路径上的每一步只能从一个数走到下一层上和它最近的左边的那个数或者右边的那个数。时间限制:1000内存限制:65536输入的是一行是一个整数N (1 < N _中国电子学会c++四级

多个EL表达式进行比较-程序员宅基地

文章浏览阅读477次。2019独角兽企业重金招聘Python工程师标准>>> ..._多个el表达式

calendar vue日期选择组件 基于 vue 2.0高性能日历组件(vue2-datepick)-程序员宅基地

文章浏览阅读2.4k次。一、点击文本框,选择日期,把日期赋值到文本框中。 二、日期组件使用1、安装vue2-datepicknpm install vue2-datepick --save2、初始化,在main.js中加入以下:import Calendar from 'vue2-datepick';Vue.use(Calendar);3、使用&lt;template&gt;..._vue2-datepick

Eigen快速入门-程序员宅基地

文章浏览阅读1k次。Eigen 快速入门_eigen

Linux纯干货知识总结_linux干货总结-程序员宅基地

文章浏览阅读364次。Linux纯干货知识总结 | 面试专用绝对路径和相对路径绝对路径以正斜杠开始完整的文件的位置路径可用于任何想置顶一个文件名的时候相对路径不以斜线开始置顶相对于当前工作目录或某目录的位置可以作为一个简短的形式指定一个文件名-基名:basename,就是文件本身的名字-目录名:dirname ,就是它所在的文件夹名更改目录cd 改变目录使用绝对或相对路径cd/home/wangcd home/wang切换至父目录:cd切换至以..._linux干货总结

推荐文章

热门文章

相关标签