精华内容
下载资源
问答
  • 之前我们介绍了排他锁,其实innodb下的记录锁(也叫行锁),间隙锁,next-key锁统统属于排他锁。 行锁 记录锁其实很好理解,对表中的记录加锁,叫做记录锁,简称行锁。 生活中的间隙锁 编程的思想源于生活,生活中...

    你需要知道的
    之前我们介绍了排他锁,其实innodb下的记录锁(也叫行锁),间隙锁,next-key锁统统属于排他锁。

    行锁
    记录锁其实很好理解,对表中的记录加锁,叫做记录锁,简称行锁。

    生活中的间隙锁
    编程的思想源于生活,生活中的例子能帮助我们更好的理解一些编程中的思想。
    生活中排队的场景,小明,小红,小花三个人依次站成一排,此时,如何让新来的小刚不能站在小红旁边,这时候只要将小红和她前面的小明之间的空隙封锁,将小红和她后面的小花之间的空隙封锁,那么小刚就不能站到小红的旁边。
    这里的小红,小明,小花,小刚就是数据库的一条条记录。
    他们之间的空隙也就是间隙,而封锁他们之间距离的锁,叫做间隙锁。

    Mysql中的间隙锁
    下表中(见图一),id为主键,number字段上有非唯一索引的二级索引,有什么方式可以让该表不能再插入number=5的记录?


    图一

    根据上面生活中的例子,我们自然而然可以想到,只要控制几个点,number=5之前不能插入记录,number=5现有的记录之间不能再插入新的记录,number=5之后不能插入新的记录,那么新的number=5的记录将不能被插入进来。

    那么,mysql是如何控制number=5之前,之中,之后不能有新的记录插入呢(防止幻读)?
    答案是用间隙锁,在RR级别下,mysql通过间隙锁可以实现锁定number=5之前的间隙,number=5记录之间的间隙,number=5之后的间隙,从而使的新的记录无法被插入进来。

    间隙是怎么划分的?

    注:为了方面理解,我们规定(id=A,number=B)代表一条字段id=A,字段number=B的记录,(C,D)代表一个区间,代表C-D这个区间范围。

    图一中,根据number列,我们可以分为几个区间:(无穷小,2),(2,4),(4,5),(5,5),(5,11),(11,无穷大)。
    只要这些区间对应的两个临界记录中间可以插入记录,就认为区间对应的记录之间有间隙。
    例如:区间(2,4)分别对应的临界记录是(id=1,number=2),(id=3,number=4),这两条记录中间可以插入(id=2,number=3)等记录,那么就认为(id=1,number=2)与(id=3,number=4)之间存在间隙。

    很多人会问,那记录(id=6,number=5)与(id=8,number=5)之间有间隙吗?
    答案是有的,(id=6,number=5)与(id=8,number=5)之间可以插入记录(id=7,number=5),因此(id=6,number=5)与(id=8,number=5)之间有间隙的,

    间隙锁锁定的区域
    根据检索条件向左寻找最靠近检索条件的记录值A,作为左区间,向右寻找最靠近检索条件的记录值B作为右区间,即锁定的间隙为(A,B)。
    图一中,where number=5的话,那么间隙锁的区间范围为(4,11);

    间隙锁的目的是为了防止幻读,其主要通过两个方面实现这个目的:
    (1)防止间隙内有新数据被插入
    (2)防止已存在的数据,更新成间隙内的数据(例如防止numer=3的记录通过update变成number=5)

    innodb自动使用间隙锁的条件:
    (1)必须在RR级别下
    (2)检索条件必须有索引(没有索引的话,mysql会全表扫描,那样会锁定整张表所有的记录,包括不存在的记录,此时其他事务不能修改不能删除不能添加)

    接下来,通过实际操作观察下间隙锁的作用范围


    图三 表结构


    案例一:

    session 1:
    start  transaction ;
    select  * from news where number=4 for update ;
     
    session 2:
    start  transaction ;
    insert into news value(2,4);#(阻塞)
    insert into news value(2,2);#(阻塞)
    insert into news value(4,4);#(阻塞)
    insert into news value(4,5);#(阻塞)
    insert into news value(7,5);#(执行成功)
    insert into news value(9,5);#(执行成功)
    insert into news value(11,5);#(执行成功)
    

    检索条件number=4,向左取得最靠近的值2作为左区间,向右取得最靠近的5作为右区间,因此,session 1的间隙锁的范围(2,4),(4,5),如下图所示:



    间隙锁锁定的区间为(2,4),(4,5),即记录(id=1,number=2)和记录(id=3,number=4)之间间隙会被锁定,记录(id=3,number=4)和记录(id=6,number=5)之间间隙被锁定。

    因此记录(id=2,number=4),(id=2,number=2),(id=4,number=4),(id=4,number=5)正好处在(id=3,number=4)和(id=6,number=5)之间,所以插入不了,需要等待锁的释放,而记录(id=7,number=5),(id=9,number=5),(id=11,number=5)不在上述锁定的范围内,因此都会插入成功。


    案例二:

    session 1:
    start  transaction ;
    select  * from news where number=13 for update ;
     
    session 2:
    start  transaction ;
    insert into news value(11,5);#(执行成功)
    insert into news value(12,11);#(执行成功)
    insert into news value(14,11);#(阻塞)
    insert into news value(15,12);#(阻塞)
    update news set id=14 where number=11;#(阻塞)
    update news set id=11 where number=11;#(执行成功)
    
    检索条件 number= 13,向左取得最靠近的值 11作为左区间,向右由于没有记录因此取得无穷大作为右区间,因此,session 1的间隙锁的范围( 11,无穷大),如下图所示:


    此表中没有number=13的记录的,innodb依然会为该记录左右两侧加间隙锁,间隙锁的范围(11,无穷大)。

    有人会问,为啥update news set id=14 where number=11会阻塞,但是update news set id=11 where number=11却执行成功呢?

    间隙锁采用在指定记录的前面和后面以及中间的间隙上加间隙锁的方式避免数据被插入,此图间隙锁锁定的区域是(11,无穷大),也就是记录(id=13,number=11)之后不能再插入记录,update news set id=14 where number=11这条语句如果执行的话,将会被插入到(id=13,number=11)的后面,也就是在区间(11,无穷大)之间,由于该区间被间隙锁锁定,所以只能阻塞等待,而update news set id=11 where number=11执行后是会被插入到(id=13,number=11)的记录前面,也就不在(11,无穷大)的范围内,所以无需等待,执行成功。


    案例三:

    session 1:
    start  transaction ;
    select  * from news where number=5 for update;
     
    session 2:
    start  transaction ;
    insert into news value(4,4);#(阻塞)
    insert into news value(4,5);#(阻塞)
    insert into news value(5,5);#(阻塞)
    insert into news value(7,11);#(阻塞)
    insert into news value(9,12);#(执行成功)
    insert into news value(12,11);#(阻塞)
    update news set number=5 where id=1;#(阻塞)
    update news set id=11 where number=11;#(阻塞)
    update news set id=2 where number=4 ;#(执行成功)
    update news set id=4 where number=4 ;#(阻塞)
    

    检索条件number=5,向左取得最靠近的值4作为左区间,向右取得11为右区间,因此,session 1的间隙锁的范围(4,5),(5,11),如下图所示:



    有人会问,为啥insert into news value(9,12)会执行成功?间隙锁采用在指定记录的前面和后面以及中间的间隙上加间隙锁的方式避免数据被插入,(id=9,number=12)很明显在记录(13,11)的后面,因此不再锁定的间隙范围内。

    为啥update news set number=5 where id=1会阻塞?
    number=5的记录的前面,后面包括中间都被封锁了,你这个update news set number=5 where id=1根本没法执行,因为innodb已经把你可以存放的位置都锁定了,因为只能等待。

    同理,update news set id=11 where number=11由于记录(id=10,number=5)与记录(id=13,number=11)中间的间隙被封锁了,你这句sql也没法执行,必须等待,因为存放的位置被封锁了。


    案例四:

    session 1:
    start  transaction;
    select * from news where number>4 for update;
     
    session 2:
    start  transaction;
    update news set id=2 where number=4 ;#(执行成功)
    update news set id=4 where number=4 ;#(阻塞)
    update news set id=5 where number=5 ;#(阻塞)
    insert into news value(2,3);#(执行成功)
    insert into news value(null,13);#(阻塞)
    

    检索条件number>4,向左取得最靠近的值4作为左区间,向右取无穷大,因此,session 1的间隙锁的范围(4,无穷大),如下图所示:


    session2中之所以有些阻塞,有些执行成功,其实就是因为插入的区域被锁定,从而阻塞。


    next-key锁
    next-key锁其实包含了记录锁和间隙锁,即锁定一个范围,并且锁定记录本身,InnoDB默认加锁方式是next-key 锁。
    上面的案例一session 1中的sql是:select * from news where number=4 for update ;
    next-key锁锁定的范围为间隙锁+记录锁,即区间(2,4),(4,5)加间隙锁,同时number=4的记录加记录锁。

    展开全文
  • 记录锁

    千次阅读 2018-09-28 20:49:09
    记录锁的功能是:当一个进程正在读或者修改文件的某一个部分时,它可以阻止其他进程修改同一文件区。记录锁其实是 字节范围锁,因为它锁定的只是文件中的一个区域,也可能是整个文件。 1.fcntl记录锁 SVR3通过...

    记录锁的功能是:当一个进程正在读或者修改文件的某一个部分时,它可以阻止其他进程修改同一文件区。记录锁其实是

    字节范围锁,因为它锁定的只是文件中的一个区域,也可能是整个文件。

    1.fcntl记录锁

    SVR3通过fcntl函数增加了记录锁功能。fcntl函数的原型已经在以前给出,这边再重复一次。

    #include<fcntl.h>
    
    int fcntl(int filedes, int cmd, .../* struct flock *flockptr */);
    
    //成功则依赖于cmd,出错则返回-1.

    对于记录锁,cmd是F_GETLK、F_SETLK或F_SETLKW。第三个参数是一个指向flock结构的指针。

    struct flock{
    
    short l_type; //F_RDLCK,F_WRLCK, or F_UNLCK
    
    off_t l_start; //offset in bytes, relative to l_whence
    
    short l_whence; //SEEK_SET, SEEK_CUR or SEEK_END
    
    off_t l_len; //length in bytes; 0 means lock to EOF
    
    pid_t l_pid; //returned with F_GETLK
    
    };

    关于加锁解锁区域注意以下几点:

     

    1.l_start是相对偏移量,l_whence决定了相对偏移量的起点。这与lseek函数中最后两个参数类似。

    2.该区域可以在当前文件尾端处开始或越过其尾端处开始,但是不能在文件起始位置之前开始。

    3.如若l_len为0,则表示锁的区域从其起点(由l_start和l_whence决定)开始直至最大可能偏移量为止。(也就是不管

    添加到该文件中多少数据,它们都处于锁的范围内)

    4.为了锁整个文件,我们设置l_start和l_whence,使锁的起点在文件起始处,并且说明l_en为0.

     

    上面说到的读写锁和线程互斥中的读写锁原理差不多:

     

    以下说明fcntl函数的三种命令:

    F_GETLK:判断由flockptr所描述的锁是否会被另外一把锁所排斥。如果存在一把锁,它阻止创建由flockptr所描述的锁,

    则把该现存锁的信息写到flockptr指向的结构中,如果不存在这中情况,则除了将l_type设置为UNLCK之外,flockptr所指向

    结构的其他信息保持不变。

    F_SETLK:设置由flockptr所描述的锁,如果试图建立一把锁(读锁或者写锁),而按上述兼容性规则不能允许,则fcntl立即

    出错返回,此时errno设置为EACCES或EAGAIN。此命令也用来消除由flockptr说明的锁(l_type为UNLOCK)

    F_SETLKW:这是F_SETLK的阻塞版本,如果因为当前在所请求区间的某个部分另一个进程已经有一把锁,因而按兼容性

    规则由flockptr所请求的锁不能被创建,则使调用进程休眠,如果请求创建的锁已经可用或者休眠由信号终端,则该进程被唤醒。

     

    在设置或释放文件上的锁时,系统按照要求组合或裂开相邻区,例如,若字节100~199是加锁区,需解锁第150字节,则内核

    将维持两把锁,一把用于字节100~149,另一把用于字节151~199.

     

    假定我们又对第150字节设置锁,那么系统将会把三个相邻的加锁区合并成一个区,其结果如上图的第一图所示。

     

    实践:

    lock.c

    #include <stdio.h>
    
    #include <fcntl.h>
    
    
    int main(void){
    
    struct flock lock;
    
    int fd;
    
    if((fd = open("lock.txt",O_RDWR))<0){
    
    perror("open");
    
    return -1;
    
    }
    
    
    //printf("fd:%d\n",fd);
    
    printf("pid:%d\n",getpid());
    
    
    lock.l_type=F_WRLCK;
    
    lock.l_start = 4;
    
    lock.l_whence = SEEK_SET;
    
    lock.l_len = 1;
    
    
    if(fcntl(fd,F_SETLK, &lock) < 0){
    
    perror("fcntl");
    
    return -1;
    
    }
    
    
    while(1){
    
    sleep(1);
    
    }
    
    return 0;
    
    }
    
    


    chlok.c

    
    
    #include <stdio.h>
    
    #include <fcntl.h>
    
    
    int main(void){
    
    struct flock lock;
    
    int fd;
    
    if((fd = open("lock.txt",O_RDWR))<0){
    
    perror("open");
    
    return -1;
    
    }
    
    //printf("fd:%d\n",fd);
    
    
    lock.l_type=F_WRLCK;
    
    lock.l_start = 3;
    
    lock.l_whence = SEEK_SET;
    
    lock.l_len = 2;
    
    
    if(fcntl(fd,F_GETLK, &lock) < 0){
    
    perror("fcntl");
    
    }
    
    
    if(lock.l_type == F_UNLCK){
    
    printf("not locked.\n");
    
    }else{
    
    printf("lock.\n");
    
    printf("lock.l_type:%s.\n",(lock.l_type == F_WRLCK)?"F_WRLCK":"not F_WRLCK");
    
    printf("lock.l_start:%ld.\n",lock.l_start);
    
    printf("lock.l_whence:%s.\n",(lock.l_whence == SEEK_SET)?"SEEK_SET":"not SEEK_SET");
    
    printf("lock.l_len:%ld.\n",lock.l_len);
    
    printf("lock.l_pid:%d.\n",lock.l_pid);
    
    }
    
    
    return 0;
    
    }

     

    root@gmdz-virtual-machine:~# cat lock.txt
    1234567890

     

    先运行lock,再运行chlock。

     

    root@gmdz-virtual-machine:~# ./lock
    pid:4181

     

    root@gmdz-virtual-machine:~# ./chlock
    lock.
    lock.l_type:F_WRLCK.
    lock.l_start:4.
    lock.l_whence:SEEK_SET.
    lock.l_len:1.
    lock.l_pid:4181.

     

    因为进程4181在锁定了字节5,所以chlock在锁定字节4,5时出错,flock中记录当前锁的信息。

     

    2.锁的隐含继承和释放

    关于记录锁的自动继承和释放有三条规则:

    1.第一,当一个进程终止时,它所建立的锁全部释放。第二,任何时候关闭一个描述符时,则该进程通过这一描述符可以引用

    的文件上的任何一把锁都被释放,这意味着如果执行下列四步:

     fd1 = open(pathname, ...);

    read_lock(fd1,...);

    fd2 = dup(fd1);

    close(fd2);

    则在close(fd2)后,在fd1上设置的锁被释放。如果将dup换成open,以打开另一描述符上的同一文件,其效果也是一样的。

    2.由fork产生的子进程不继承父进程所设置的锁。

    3.在执行exec后,新程序可以继承原执行程序的锁。但是,如果对一个文件描述符设置了close-on-exec标志,那么当作为exec

    的一部分关闭该文件描述符时,对相应文件的所有锁都被释放了。

     

    3.建议性锁和强制性锁

    1.建议性锁是这样规定的:每个使用上锁文件的进程都要检查是否有锁存在,当然还得尊重已有的锁。内核和系统总体上

    都坚持不使用建议性锁,它们依靠程序员遵守这个规定。(Linux默认是采用建议性锁)

    2.强制性锁是由内核执行的。当文件被上锁来进行写入操作时,在锁定该文件的进程释放该锁之前,内核会阻止任何对该

    文件的读或写访问,每次读或写访问都得检查锁是否存在。

     本文来自 TODD911 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/todd911/article/details/18654693?utm_source=copy

    展开全文
  • mysql记录锁

    千次阅读 2018-09-29 10:55:50
    记录锁 记录锁是锁住记录,锁住索引记录,而不是真正的数据记录 锁是非主键索引,会在索引记录上加锁后,在去主键索引上加锁 表上没有索引,会在隐藏的主键索引上加锁 如果要锁的列没有索引,进行全表记录加锁 ...

    该文章在Innodb引擎下

    记录锁

    记录锁是锁住记录,锁住索引记录,而不是真正的数据记录

    • 锁是非主键索引,会在索引记录上加锁后,在去主键索引上加锁
    • 表上没有索引,会在隐藏的主键索引上加锁
    • 如果要锁的列没有索引,进行全表记录加锁

    间隙锁

    不是针对某一记录加锁,而是锁定一个范围,也被称为gap锁,不会阻塞其他gap锁,但会阻塞插入间隙锁,这也是防止幻读的关键(RR隔离,Innodb默认隔离)

    next-key锁

    该锁是记录锁加gap锁,在RR隔离级别下,对行的扫描、锁定都是使用这种锁。如果查询中包含唯一索引,就会只适用记录锁。因为唯一索引能确定记录行数,其他索引不能确定行数,有可能在其他事务中添加这个索引的数据导致幻读。

    插入意向锁

    官方解释:

    An insert intention lock is a type of gap lock set by INSERT operations prior to row insertion. This lock signals the intent to insert in such a way that multiple transactions inserting into the same index gap need not wait for each other if they are not inserting at the same position within the gap. Suppose that there are index records with values of 4 and 7. Separate transactions that attempt to insert values of 5 and 6, respectively, each lock the gap between 4 and 7 with insert intention locks prior to obtaining the exclusive lock on the inserted row, but do not block each other because the rows are nonconflicting.

    可以看出插入意向锁是在插入的时候产生的,在多个事务同时写入不同数据至同一索引间隙的时候,并不需要等待其他事务完成,不会发生锁等待。

    这里要说明的是如果有间隙锁了,插入意向锁会被阻塞。

    MVCC

    MVCC,多版本并发控制技术。在 InnoDB 中,在每一行记录的后面增加两个隐藏列,记录创建版本号和删除版本号。通过版本号和行锁,从而提高数据库系统并发性能。

    MVCC,读有两种方式:

    • 快照读:读取的历史数据,简单的 select 语句,不加锁,MVCC 实现可重复读,使用的是 MVCC 机制读取 undo 中的已经提交的数据。所以它的读取是非阻塞的。
    • 当前读:需要加锁的语句,update,insert,delete,select…for update 等等都是当前读。

    在 RR 隔离级别下的快照读,不是以 begin 事务开始的时间点作为 snapshot 建立时间点,而是以第一条 select 语句的时间点作为 snapshot 建立的时间点。以后的 select 都会读取当前时间点的快照值。

    在 RC 隔离级别下每次快照读均会创建新的快照,所以RC隔离级别下会出现幻读。

    具体的原理是通过每行会有两个隐藏的字段一个是用来记录当前事务,一个是用来记录回滚的指向 Undolog。利用 Undolog 就可以读取到之前的快照,不需要单独开辟空间记录。

    死锁

    相互等待资源造成死锁,上面描述中说,有间隙锁时,意向插入锁会被阻塞。当两个事务,在同一间隙上都加锁(间隙锁相同兼容,不会阻塞),同时在这一间隙内插入数据,会导致相互等待间隙锁,造成死锁。

    防止死锁

    • 以固定的顺序访问表和行。交叉访问更容易造成事务等待回路。
    • 尽量避免大事务,占有的资源锁越多,越容易出现死锁。建议拆成小事务。
    • 降低隔离级别。如果业务允许,将隔离级别调低也是较好的选择,比如将隔离级别从 RR 调整为 RC,可以避免掉很多因为 gap 锁造成的死锁。
    • 为表添加合理的索引。防止没有索引出现表锁,出现死锁的概率会突增。
    展开全文
  • 文件锁和记录锁

    千次阅读 2018-07-13 10:21:55
    http://blog.chinaunix.net/uid-23634108-id-2393492.html 下面介绍两种两种Linux下对文件加锁的两种方式一、文件思想:假设有一个文件A。创建一个加锁文件B,通过不同的进程互斥的访问此加锁文件B达到互斥的访问...

    http://blog.chinaunix.net/uid-23634108-id-2393492.html

     

    下面介绍两种两种Linux下对文件加锁的两种方式
    一、文件锁
    思想:
    假设有一个文件A。创建一个加锁文件B,通过不同的进程互斥的访问此加锁文件B达到互斥的访问文件A的目的。
    源码如下

    #include "stdio.h"
    #include <time.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <mysql/mysql.h>
    #include <errno.h>

    /*
    此种方法只能锁整个文件,访问被锁的文件后回直接返回
    */

    int main(int argc, char* argv[])
    {
     int fdB;
     FILE* pA;
     
     fdB = open("B.lock", O_CREAT | O_EXCL, 0644);
     if (fdB < 0 && errno == EEXIST)
     {
      // 其实是判断文件B.lock是否已经存在
      printf("File A.dat is already locked./n");
      return -1;

     } 
     else if (fdB < 0)
     {
      perror("error");
      return -1;
     }
     
     //下面进行对文件A.dat的访问
     pA = fopen("A.dat", "w");

     //...
     //...
     fclose(pA);
     
     close(fdB);
     unlink("B.lock"); // 去掉对加锁文件的引用,删除 "B.lock"
     return 0;
    }

    二、记录锁
    第二种方式可以实现只锁文件的某个部分,并且可以灵活的选择是阻塞方式还是立刻返回方式。

    记录锁通过系统调用 fcntl来实现
    #include <fcntl.h>
    int fcntl(int fd, int command, long arg);

    struct flock
    {
     short l_type; // 锁的类型
     short l_whence;// 锁的起始
     off_t l_start;// 锁的起始偏移,与l_whence相关
     off_t l_len; // 锁住多少字节
     off_t l_pid; // 拥有锁的进程pid
    }

    调用fcntl进行加锁的操作时,arg是指向结构体flock的指针。
    l_type表示加锁的类型,它可以是以下值:
    F_RDLCK 读锁(共享锁)
    F_WRLCK 写锁(独占锁)
    F_UNLCK 释放锁

    参数l_whence和l_start表示锁的起始地址,含义与lseek中的同名参数相同。
    l_whence为以下三个值之一:
    SEEK_SET: 从文件开始计算
    SEEK_CUR: 从当前计算
    SEEK_END:从文件末尾计算

    参数
    l_len表示锁的长度是多少字节,如果为0.表示锁一直延伸到文件按的末尾。
    l_pid: 仅在查询锁的时候才用,它是这个锁的拥有者的进程pid

    fcntl有三个命令和加锁有关,操作通过参数command来传递,它可以是以下的三个值之一:
    F_SETLK: 按照arg进行加锁和解锁的处理,如果因为冲突不能上锁,立刻返回并且errno被设置为EAGAIN。
    如果l_type是F_UNLCK,已存在的锁被释放。
    F_SETLKW:相当于阻塞式的F_SETLK(W的含义是wait)。如果要上锁的区域被其他进程锁住,使申请不能马上成功,则进入睡眠,
    等待原来的锁被释放,在上锁成功后返回,如果在进程阻塞时有信号发生,返回并且errno被设为EAGAIN
    F_GETLK:检查是否可以申请由arg决定的锁。如果不和别的进程已经存在的锁发生冲突,arg指向的结构flock中的l_type被赋为
    F_UNLCK,其余的成员不变。如果不能给与锁,l_pid被赋为发生冲突的进程的pid。这两种情况下函数都返回0。

    下面是一些关于记录锁的规则:
    1)锁可以延伸到文件按目前的结尾之后,但是不能扩展到文件头之前,也不能从文件头之前开始。
    2)如果l_len为0,锁得到最大长度的延伸,这是我们可以从文件的任何地方开始,向后锁住所有的文件数据,并锁住以后添加到
    文件末尾的数据,不管添加多少数据。
    3)要锁住整个文件,设l_start为0,l_whence为SEEK_SET,l_len为0。
    4)如果一块区域被一个进程加了读锁,则另外的进程可以再给它加上读锁,但是不能加写锁。(共享锁)。
    如果一块区域被一个进程加了些锁,则它不能为另外的进程加上读锁或写锁(独占锁)。

    5)锁的释放:
    当进程终止时,它所有的锁都会被释放(不同与文件锁)。
    当文件描述符关闭时,在这个进程中,加在该文件描述符上的所有锁被释放


    一下是示例代码:

    #include "stdio.h"
    #include <time.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <mysql/mysql.h>
    #include <errno.h>


    int main(int argc, char* argv[])
    {
     char cmdStr[128];
     int fd = 0;
     struct flock lockinfo;
     lockinfo.l_type = F_WRLCK;
     lockinfo.l_whence = SEEK_SET;
     lockinfo.l_start = 0;
     lockinfo.l_len = 0;
     
     fd = open("Data.dat", O_CREAT | O_RDWR | O_APPEND, 0666);
     if (fd < 0)
     {
      return 0;
     }
     // 文件加锁(阻塞式)
     fcntl(fd, F_SETLKW, &lockinfo);

     // 写文件
     strcpy(cmdStr, "wu di zui ji mo./n");
     write(fd, (void*)cmdStr, strlen(cmdStr));
     printf("HAHA/n");
     sleep(10);
     close(fd);// 释放记录锁
     return 1;

    }

     

    展开全文
  • 记录锁、间隙锁和临键锁

    千次阅读 2020-05-05 19:34:05
    记录锁、间隙锁和临键锁 Record Lock A record lock is a lock on an index record. For example,SELECT c1 FROM t WHERE c1 = 10 FOR UPDATE; prevents any other transaction from inserting, updating, or ...
  • Linux记录锁(文件锁)

    千次阅读 2018-09-24 09:37:04
    记录锁(record locking)的功能是: 当第一个进程正在读或修改文件的某个部分时,使用记录锁可以阻止其他进程修改同一文件区。 “记录”这个词是一种误用,因为UNIX系统内核根本没有使用文件记录这种概念。 一个更...
  • 推荐:mysql锁 innodb下的记录锁,间隙锁,next-key锁

    万次阅读 多人点赞 2017-06-26 01:06:44
    之前我们介绍了排他锁,其实innodb下的记录锁(也叫行锁),间隙锁,next-key锁统统属于排他锁。 行锁 记录锁其实很好理解,对表中的记录加锁,叫做记录锁,简称行锁。 生活中的间隙锁 编程的思想源于生活,生活中...
  • 记录锁(record lock) 这是一个索引记录锁,它是建立在索引记录上的锁(主键和唯一索引都算),很多时候,锁定一条数据,由于无索引,往往会导致整个表被锁住,建立合适的索引可以防止扫描整个表。 如:开两个会话...
  • Oracle记录锁住解决办法

    千次阅读 2018-05-30 23:48:44
    Oracle中查询表的SQL:select sess.sid, sess.serial#, lo.oracle_username, lo.os_user_name, ao.object_name, lo.locked_mode from v$locked_object lo, dba_objects ao, v$session sess where ao.object_id = lo...
  • 记录锁(Record Locks) 顾名思义,记录锁就是为某行记录加锁,它封锁该行的索引记录: -- id 列为主键列或唯一索引列 SELECT * FROM table WHERE id = 1 FOR UPDATE; 复制代码 id 为 1 的记录行会被锁住。 ...
  • 【Linux多进程同步】记录锁

    千次阅读 2016-03-23 21:18:16
    记录锁相当于线程同步中读写锁的一种扩展类型,可以用来对有亲缘或无亲缘关系的进程进行文件读与写的同步,通过 fcntl 函数来执行上锁操作。尽管读写锁也可以通过在共享内存区来进行进程的同步,但是fcntl记录上锁...
  • 【Linux】记录锁

    千次阅读 2015-07-02 16:40:55
    记录锁的功能是:当一个进程正在读或修改文件的某个部分时,它可以阻止其它进程修改同一文件区。fcntl函数可以实现这一功能。#include <fcntl.h>int fcntl(int fd, int cmd, ... /* arg */ );对于记录锁,cmd是F_...
  • 中最基本的机制: 共享(S  – Shared Locks) 排它(X  – Exclusive Locks) 意向共享(IS  – Intention Shared Locks) 意.....
  • 本文主要针对InnoDB的行锁研究,避免陷入间隙而导致死锁等不利现象。
  • Linux进程同步之记录锁(fcntl)

    千次阅读 2013-06-28 16:04:53
    记录锁相当于线程同步中读写锁的一种扩展类型,可以用来对有亲缘或无亲缘关系的进程进行文件读与写的同步,通过fcntl函数来执行上锁操作。尽管读写锁也可以通过在共享内存区来进行进程的同步,但是fcntl记录上锁往往...
  • Linux记录锁

    万次阅读 2016-10-08 15:33:59
    记录锁的功能是:当一个进程正在读或者修改文件的某一个部分时,它可以阻止其他进程修改同一文件区。记录锁其实是 字节范围锁,因为它锁定的只是文件中的一个区域,也可能是整个文件。1.fcntl记录锁SVR3通过fcntl...
  • 今天开发测试时候,idea debug模式下报错,数据库表事务没有提交,idea服务强制关闭,导致数据库表某一条记录 最后发现这条数据被, 查询资料解决方法如下: show processlist; 找出线程ID kill 线程号id ...
  • 如果该库中所有函数都以一致的方法处理记录锁,则称使用这些函数存取数据库的任何进程集为合作进程( cooperatingpro c e ss)。如果这些函数是唯一的用来存取数据库的函数,那么它们使用建议性锁是可行的。但是建议...
  • UNIX/LINUX编程学习之文件锁、记录锁

    千次阅读 2011-09-14 08:40:30
    转自: ... 锁定中的几个概念   文件锁定的是整个文件,而记录锁定只锁定文件的某一特定部分。UNIX 的记录指的是从文件的某一相对位置开始的一段连续的字节流,它不同于其它以强制性记录结构
  • linux下的记录锁

    千次阅读 2012-01-05 23:27:09
    有三种不同的文件,这三种都是“咨询性”的,也就是说它们依靠程序之间的合作,所以一个项目中的所有程序封锁政策的一致是非常重要的,当你的程序需要和第三方软件共享文件时应该格外地小心。 有些程序利用诸如...
  • 一、读写 1.基本概念 当有一个线程已经持有互斥时,互斥将所有试图进入临界区的线程都阻塞住。但是考虑一种情形,当前持有互斥的线程只是要读访问共享资源,而同时有其它几个线程也想读取这个共享资源,但是...
  • -- 查询 ...</pre><pre name="code" class="sql">select object_name,machine... 根据查询出来的记录的SID和SERIAL#来释放session -- 如果提示权限不足的话,请用DBA用户登录进行解锁操作。
  • Unix记录锁使用总结

    千次阅读 2009-12-13 17:27:00
    1. 原理说明在Unix系统中,记录锁的功能是:一个进程正在读或修改文件的某个部分时,可以阻止其他进程修改同一文件区。即其锁定的是文件的一个区域或整个文件。记录锁有两种类型:共享读锁,独占写锁。基本规则是:...
  • 1、兼容性:加了S记录,允许其他事务再加S,不允许其他事务再加X 2、加锁方式:select…lock in share mode 2.2 排他Exclusive Locks(X) 1、兼容性:加了X记录,不允许其他事务再加S或者X 2、...
  • linux高级IO——记录锁

    千次阅读 2010-12-29 20:03:00
    记录锁的功能  当一个进程正在读或修改文件的某个部分时,它可以阻止其他进程修改同一文件区。我们不应该从字面上去理解记录锁,实际上它应该叫“区域锁”,因为它锁定的只是文件的一个(也可能是整个文件)。...
  • 记录锁,多进程,临界区

    千次阅读 2014-10-20 23:22:37
    1. 记录锁概念和功能 当两个人同时编辑一个文件时,其后果将如何呢?在很多U N I X系统中,该文件的最后状态取决于写该文件的最后一个进程。但是对于有些应用程序,例如数据库,有时进程需要确保它正在单独写一...
  • oracle某条记录后处理

    千次阅读 2018-09-18 16:24:18
    由于在PLSQL Developer执行update或某种操作时没有commit,导致oracle将该条记录锁住了。 解决办法: 1. 查找锁住的记录 select s.sid, s.serial# from v$locked_object lo, dba_objects ao, v$session s where ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 429,444
精华内容 171,777
关键字:

记录锁