SqlServer加锁

SqlServer加锁,第1张

概述为什么要引入锁 ? 多个用户同时对数据库的并发 *** 作时会带来以下数据不一致的问题。   select加共享锁,insert、update、delete加排他锁。   悲观锁(Pessimistic Lock), 顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行

为什么要引入锁 ?
多个用户同时对数据库的并发 *** 作时会带来以下数据不一致的问题。

 

select加共享锁,insert、update、delete加排他锁。

 

悲观锁(@R_749_3270@ Lock),顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做 *** 作之前先上锁。 通过 jdbc 实现时 sql 语句只要在整个语句之后加 for update 即可。例如: select …for update

乐观锁(Optimistic Lock),顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库如果提供类似于write_condition机制的其实都是提供的乐观锁。

两种锁各有优缺点,不可认为一种好于另一种,像乐观锁适用于写比较少的情况下,即冲突真的很少发生的时候,这样可以省去了锁的开销,加大了系统的整个吞吐量。但如果经常产生冲突,上层应用会不断的进行retry,这样反倒是降低了性能,所以这种情况下用悲观锁就比较合适

 

共享锁:(读取) *** 作创建的锁。其他用户可以并发读取数据,但任何事物都不能获取数据上的排它锁,直到已释放所有共享锁。 共享锁(S锁)又称为读锁,若事务T对数据对象A加上S锁,则事务T只能读A;其他事务只能再对A加S锁,而不能加X锁,直到T释放A上的S锁。这就保证了其他事务可以读A,但在T释放A上的S锁之前不能对A做任何修改。

共享锁的使用 在第一个连接中执行以下语句 begin tran select * from table1 WITH(HolDLOCK) -holdlock人为加锁 where B='b2' waitfor delay '00:00:30' --等待30秒 commit tran 在第二个连接中执行以下语句 select A,C from table1 update table1 set A='aa' 若同时执行上述两个语句,则第二个连接中的select查询可以执行 而update必须等待第一个事务释放共享锁转为排它锁后才能执行 即要等待30秒

 

排它锁:排它锁又称为写锁((eXclusive lock,简记为X锁)),若事物T对数据对象A加上X锁,则只允许T读取和修改A,其它任何事务都不能再对A加任何类型的锁,直到T释放A上的锁。它防止任何其它事务获取资源上的锁,直到在事务的末尾将资源上的原始锁释放为止。 排它锁的使用

在第一个连接中执行以下语句
begin tran
update table1
set A='aa'
where B='b2'
waitfor delay '00:00:30' --等待30秒
commit tran
在第二个连接中执行以下语句
begin tran
select * from table1
where B='b2'
commit tran

若同时执行上述两个语句,则select查询必须等待update执行完毕才能执行即要等待30秒


互斥锁(Mutex)

互斥锁是一个互斥的同步对象,意味着同一时间有且仅有一个线程可以获取它。

互斥锁可适用于一个共享资源每次只能被一个线程访问的情况

using System;using System.Collections.Generic;using System.linq;using System.Text;  using System.Threading;  namespace MyTTCon{    class shareRes    {        public static int count = 0;        public static Mutex mutex = new Mutex();    }      class IncThread    {        int number;        public Thread thrd;        public IncThread(string name,int n)        {            thrd = new Thread(this.run);            number = n;            thrd.name = name;            thrd.Start();        }        voID run()        {            Console.Writeline(thrd.name + "正在等待 the mutex");            //申请            shareRes.mutex.WaitOne();            Console.Writeline(thrd.name + "申请到 the mutex");            do            {                Thread.Sleep(1000);                shareRes.count++;                Console.Writeline("In " + thrd.name + "ShareRes.count is " + shareRes.count);                number--;            } while (number > 0);            Console.Writeline(thrd.name + "释放 the nmutex");            //  释放            shareRes.mutex.ReleaseMutex();        }    }    class DecThread    {        int number;        public Thread thrd;        public DecThread(string name,int n)        {            thrd = new Thread(this.run);            number = n;            thrd.name = name;            thrd.Start();        }        voID run()        {            Console.Writeline(thrd.name + "正在等待 the mutex");            //申请            shareRes.mutex.WaitOne();            Console.Writeline(thrd.name + "申请到 the mutex");            do            {                Thread.Sleep(1000);                shareRes.count--;                Console.Writeline("In " + thrd.name + "ShareRes.count is " + shareRes.count);                number--;            } while (number > 0);            Console.Writeline(thrd.name + "释放 the nmutex");            //  释放            shareRes.mutex.ReleaseMutex();        }    }      class Program    {        static voID Main(string[] args)        {            IncThread mthrd1 = new IncThread("IncThread thread ",5);            DecThread mthrd2 = new DecThread("DecThread thread ",5);            mthrd1.thrd.Join();            mthrd2.thrd.Join();        }    }}



 小结:

  悲观锁:查询加锁 【select ...... for update】

  乐观锁:修改加锁 【版本号控制】

  排它锁:事务A可以查询、修改,直到事务A释放为止才可以执行下一个事务

  共享锁:事务A可以查询、修改,同时事务B也可以查询但不能修改

  互斥锁:同一资源同一时间只能被一个线程访问


参考:http://bbs.csdn.net/topics/360017582

总结

以上是内存溢出为你收集整理的SqlServer加锁全部内容,希望文章能够帮你解决SqlServer加锁所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/sjk/1171452.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-02
下一篇 2022-06-02

发表评论

登录后才能评论

评论列表(0条)

保存