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

技术标签: 高并发  数据库加锁  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

智能推荐

c# 调用c++ lib静态库_c#调用lib-程序员宅基地

文章浏览阅读2w次,点赞7次,收藏51次。四个步骤1.创建C++ Win32项目动态库dll 2.在Win32项目动态库中添加 外部依赖项 lib头文件和lib库3.导出C接口4.c#调用c++动态库开始你的表演...①创建一个空白的解决方案,在解决方案中添加 Visual C++ , Win32 项目空白解决方案的创建:添加Visual C++ , Win32 项目这......_c#调用lib

deepin/ubuntu安装苹方字体-程序员宅基地

文章浏览阅读4.6k次。苹方字体是苹果系统上的黑体,挺好看的。注重颜值的网站都会使用,例如知乎:font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, PingFang SC, Microsoft YaHei, Source Han Sans SC, Noto Sans CJK SC, W..._ubuntu pingfang

html表单常见操作汇总_html表单的处理程序有那些-程序员宅基地

文章浏览阅读159次。表单表单概述表单标签表单域按钮控件demo表单标签表单标签基本语法结构<form action="处理数据程序的url地址“ method=”get|post“ name="表单名称”></form><!--action,当提交表单时,向何处发送表单中的数据,地址可以是相对地址也可以是绝对地址--><!--method将表单中的数据传送给服务器处理,get方式直接显示在url地址中,数据可以被缓存,且长度有限制;而post方式数据隐藏传输,_html表单的处理程序有那些

PHP设置谷歌验证器(Google Authenticator)实现操作二步验证_php otp 验证器-程序员宅基地

文章浏览阅读1.2k次。使用说明:开启Google的登陆二步验证(即Google Authenticator服务)后用户登陆时需要输入额外由手机客户端生成的一次性密码。实现Google Authenticator功能需要服务器端和客户端的支持。服务器端负责密钥的生成、验证一次性密码是否正确。客户端记录密钥后生成一次性密码。下载谷歌验证类库文件放到项目合适位置(我这边放在项目Vender下面)https://github.com/PHPGangsta/GoogleAuthenticatorPHP代码示例://引入谷_php otp 验证器

【Python】matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距-程序员宅基地

文章浏览阅读4.3k次,点赞5次,收藏11次。matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距

docker — 容器存储_docker 保存容器-程序员宅基地

文章浏览阅读2.2k次。①Storage driver 处理各镜像层及容器层的处理细节,实现了多层数据的堆叠,为用户 提供了多层数据合并后的统一视图②所有 Storage driver 都使用可堆叠图像层和写时复制(CoW)策略③docker info 命令可查看当系统上的 storage driver主要用于测试目的,不建议用于生成环境。_docker 保存容器

随便推点

网络拓扑结构_网络拓扑csdn-程序员宅基地

文章浏览阅读834次,点赞27次,收藏13次。网络拓扑结构是指计算机网络中各组件(如计算机、服务器、打印机、路由器、交换机等设备)及其连接线路在物理布局或逻辑构型上的排列形式。这种布局不仅描述了设备间的实际物理连接方式,也决定了数据在网络中流动的路径和方式。不同的网络拓扑结构影响着网络的性能、可靠性、可扩展性及管理维护的难易程度。_网络拓扑csdn

JS重写Date函数,兼容IOS系统_date.prototype 将所有 ios-程序员宅基地

文章浏览阅读1.8k次,点赞5次,收藏8次。IOS系统Date的坑要创建一个指定时间的new Date对象时,通常的做法是:new Date("2020-09-21 11:11:00")这行代码在 PC 端和安卓端都是正常的,而在 iOS 端则会提示 Invalid Date 无效日期。在IOS年月日中间的横岗许换成斜杠,也就是new Date("2020/09/21 11:11:00")通常为了兼容IOS的这个坑,需要做一些额外的特殊处理,笔者在开发的时候经常会忘了兼容IOS系统。所以就想试着重写Date函数,一劳永逸,避免每次ne_date.prototype 将所有 ios

如何将EXCEL表导入plsql数据库中-程序员宅基地

文章浏览阅读5.3k次。方法一:用PLSQL Developer工具。 1 在PLSQL Developer的sql window里输入select * from test for update; 2 按F8执行 3 打开锁, 再按一下加号. 鼠标点到第一列的列头,使全列成选中状态,然后粘贴,最后commit提交即可。(前提..._excel导入pl/sql

Git常用命令速查手册-程序员宅基地

文章浏览阅读83次。Git常用命令速查手册1、初始化仓库git init2、将文件添加到仓库git add 文件名 # 将工作区的某个文件添加到暂存区 git add -u # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,不处理untracked的文件git add -A # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,包括untracked的文件...

分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120-程序员宅基地

文章浏览阅读202次。分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120

【C++缺省函数】 空类默认产生的6个类成员函数_空类默认产生哪些类成员函数-程序员宅基地

文章浏览阅读1.8k次。版权声明:转载请注明出处 http://blog.csdn.net/irean_lau。目录(?)[+]1、缺省构造函数。2、缺省拷贝构造函数。3、 缺省析构函数。4、缺省赋值运算符。5、缺省取址运算符。6、 缺省取址运算符 const。[cpp] view plain copy_空类默认产生哪些类成员函数

推荐文章

热门文章

相关标签