1.这样的情况要注意什么问题,需要加锁吗?如何加?
2.如果我改用线程来做同样的事情,需要注意什么问题,需要加读写锁吗?
3.如果使用C++的话上述问题答案会不一样吗
谢谢
13 个解决方案
#1
1、sql server会自动加锁,不需要通过程序来加锁的
2、是sql server自动加的读写锁,不需要程序来加锁。
3、c++,也是一样的
#2
对于查询,可以简单地理解为:在查询的数据上加了共享锁(在行级别加共享锁的同时,当然在表级别,也有意向共享锁,防止别人在你查询的时候把表给删除了,同理,在数据库级也有共享锁)
对于update语句,可以简单地理解为sqlserver先做查询,把要修改的记录给找到,然后在这个记录上做修改。
找记录的动作要加S锁,找到要修改的记录后会先加U锁,再将U锁升级成X锁。
至于锁加载那个级别(行锁,页锁,表锁等等),跟具体的表结构和索引类型有关
举个例子,如果按照ID更新,ID列上有索引,当更新执行中时,其他事物无法访问该ID的数据,包括读
如果表上ID上没有任何索引,加锁的就是整个表,导致整个表无法被访问
这些锁都是在事务提交之后释放的,这就要求,sql的执行后越早提交越好,
说白了还是跟sql执行效率和修改数据的量有关
我简单地测试过,用C#,同一张表,往里面写数据,开10个线程,每个线程往表中写1000条数据
这十个线程耗时900毫秒到1100毫秒不等
I3四核的个人电脑,仅做参考
#3
当然了,我的测试也有局限性,
写数据时,表结果越简单越好,也就是没有任何索引,计算列之类的,效率会高一些,
读数据时,尽可能根据具体情况加上合适的索引,效率会高一些,
这个就要求根据具体情况做衡量了,
如果是企业级应用,比如什么OA系统了,管理系统了之类的,
领导A批A部分的单子,领导B看B部门的文件,
这些系统基本上不会出现数据争用的现象,
基本上不会出现因为并发影响到使用的情况
除非用户量非常大(比如周一造成同时访问OA系统的人达到数千人甚至过万,可能出现应付不了并发的现象)
再就是系统设计的不合理
前段时间公司另外一个同事负责的OA系统,多说几千个用户,
然后周一早上容易迟到,这部分迟到的人就请别人在OA上给他们请假,
总的用户几千个,周一早上上班之前,
因为迟到同时请假的最多也就几十个,上百个,结果记录请假信息相关的表有ID重复的现象
这个竟然分析出来的问题是应付不了并发,真是可笑,
这些就是典型的例子,程度中不做任何控制,归结于数据库,是不合适的
写数据时,表结果越简单越好,也就是没有任何索引,计算列之类的,效率会高一些,
读数据时,尽可能根据具体情况加上合适的索引,效率会高一些,
这个就要求根据具体情况做衡量了,
如果是企业级应用,比如什么OA系统了,管理系统了之类的,
领导A批A部分的单子,领导B看B部门的文件,
这些系统基本上不会出现数据争用的现象,
基本上不会出现因为并发影响到使用的情况
除非用户量非常大(比如周一造成同时访问OA系统的人达到数千人甚至过万,可能出现应付不了并发的现象)
再就是系统设计的不合理
前段时间公司另外一个同事负责的OA系统,多说几千个用户,
然后周一早上容易迟到,这部分迟到的人就请别人在OA上给他们请假,
总的用户几千个,周一早上上班之前,
因为迟到同时请假的最多也就几十个,上百个,结果记录请假信息相关的表有ID重复的现象
这个竟然分析出来的问题是应付不了并发,真是可笑,
这些就是典型的例子,程度中不做任何控制,归结于数据库,是不合适的
#4
其实,之所以不需要程序加锁,是因为这些读 和 写 的锁,都是由sql server自动加的。
一般,在程序中,比如在windows中,多个线程,对一个全局变量,进行并发访问的时候,我们可以通过:
createmutex、createsemaphore等创建互斥体、信号量,这样在多线程访问全局变量时,就可以保证数据的一致性。
那么,在sql server中,当执行一个sql语句,而这个语句需要select 或者update数据的时候,由sql server自动对这个sql语句所需要读取的数据或者修改的数据,在处理数据的过程中,加锁,防止其他线程来修改。
一般,线程1在select数据的时候会加S锁,也就是共享锁,而线程2也在select同样的数据,也会加共享锁,这个时候,不会有阻塞的情况,因为读是可以共享的。
但如果线程1在读取数据,已经加了共享锁,而线程2要update,这个时候需要加上x锁,那么由于s锁和x锁,不兼容,就导致线程2被阻塞了。
一般,在程序中,比如在windows中,多个线程,对一个全局变量,进行并发访问的时候,我们可以通过:
createmutex、createsemaphore等创建互斥体、信号量,这样在多线程访问全局变量时,就可以保证数据的一致性。
那么,在sql server中,当执行一个sql语句,而这个语句需要select 或者update数据的时候,由sql server自动对这个sql语句所需要读取的数据或者修改的数据,在处理数据的过程中,加锁,防止其他线程来修改。
一般,线程1在select数据的时候会加S锁,也就是共享锁,而线程2也在select同样的数据,也会加共享锁,这个时候,不会有阻塞的情况,因为读是可以共享的。
但如果线程1在读取数据,已经加了共享锁,而线程2要update,这个时候需要加上x锁,那么由于s锁和x锁,不兼容,就导致线程2被阻塞了。
#5
加锁,肯定要加锁,但是程序上也要控制啊。3楼说的,那是数据唯一性问题。
#6
谢谢,这样我就放心了,我就怕我的程序会出莫名的问题
#7
感谢分享经验,非常有用
#8
纯读操作不会有什么影响,不过要看你是不是还有后续操作或者只有2个线程
#9
能说得再稍微具体一点不?假设我有10个线程?谢谢
#10
10个线程单纯读数据不影响,我是说你读了之后还要做什么事情?
#11
10个线程单纯读数据不影响,我是说你读了之后还要做什么事情?
纯读操作不会有什么影响,不过要看你是不是还有后续操作或者只有2个线程
能说得再稍微具体一点不?假设我有10个线程?谢谢
当然是不止读数据啊,光读数据我也知道不加锁都可以,每个线程都要更新数据的
#12
我目前的情况是有两个进程会同时读写同一张表,环境是.net 3.5或者4.0 + sql server 08,请问:
1.这样的情况要注意什么问题,需要加锁吗?如何加?
首先同意yupeigu的说法,程序上需要全局变量控制提交给SQL的变量.SQL层面上,如果是数据自动管理的锁,tzleo 回答了你的问题.
如果需要人为干预加锁,那么你可以使用Locking Hint, 请参考: http://technet.microsoft.com/en-us/library/ms172398.aspx
例子: 下面的Locking HINT保证了整个表在被某个transaction获得X锁后,完全被锁住.其它的 transaction不可以可以访问,修改该表.
Begin Trans
INSERT INTO table WITH ( TABLOCK )......
COMMIT Trans
2.如果我改用线程来做同样的事情,需要注意什么问题,需要加读写锁吗?
没看懂什么意思.
3.如果使用C++的话上述问题答案会不一样吗
程序层面,不懂
1.这样的情况要注意什么问题,需要加锁吗?如何加?
首先同意yupeigu的说法,程序上需要全局变量控制提交给SQL的变量.SQL层面上,如果是数据自动管理的锁,tzleo 回答了你的问题.
如果需要人为干预加锁,那么你可以使用Locking Hint, 请参考: http://technet.microsoft.com/en-us/library/ms172398.aspx
例子: 下面的Locking HINT保证了整个表在被某个transaction获得X锁后,完全被锁住.其它的 transaction不可以可以访问,修改该表.
Begin Trans
INSERT INTO table WITH ( TABLOCK )......
COMMIT Trans
2.如果我改用线程来做同样的事情,需要注意什么问题,需要加读写锁吗?
没看懂什么意思.
3.如果使用C++的话上述问题答案会不一样吗
程序层面,不懂
#13
我目前的情况是有两个进程会同时读写同一张表,环境是.net 3.5或者4.0 + sql server 08,请问:
1.这样的情况要注意什么问题,需要加锁吗?如何加?
首先同意yupeigu的说法,程序上需要全局变量控制提交给SQL的变量.SQL层面上,如果是数据自动管理的锁,tzleo 回答了你的问题.
如果需要人为干预加锁,那么你可以使用Locking Hint, 请参考: http://technet.microsoft.com/en-us/library/ms172398.aspx
例子: 下面的Locking HINT保证了整个表在被某个transaction获得X锁后,完全被锁住.其它的 transaction不可以可以访问,修改该表.
Begin Trans
INSERT INTO table WITH ( TABLOCK )......
COMMIT Trans
2.如果我改用线程来做同样的事情,需要注意什么问题,需要加读写锁吗?
没看懂什么意思.
3.如果使用C++的话上述问题答案会不一样吗
程序层面,不懂
非常感谢,帮了大忙了
#1
1、sql server会自动加锁,不需要通过程序来加锁的
2、是sql server自动加的读写锁,不需要程序来加锁。
3、c++,也是一样的
#2
对于查询,可以简单地理解为:在查询的数据上加了共享锁(在行级别加共享锁的同时,当然在表级别,也有意向共享锁,防止别人在你查询的时候把表给删除了,同理,在数据库级也有共享锁)
对于update语句,可以简单地理解为sqlserver先做查询,把要修改的记录给找到,然后在这个记录上做修改。
找记录的动作要加S锁,找到要修改的记录后会先加U锁,再将U锁升级成X锁。
至于锁加载那个级别(行锁,页锁,表锁等等),跟具体的表结构和索引类型有关
举个例子,如果按照ID更新,ID列上有索引,当更新执行中时,其他事物无法访问该ID的数据,包括读
如果表上ID上没有任何索引,加锁的就是整个表,导致整个表无法被访问
这些锁都是在事务提交之后释放的,这就要求,sql的执行后越早提交越好,
说白了还是跟sql执行效率和修改数据的量有关
我简单地测试过,用C#,同一张表,往里面写数据,开10个线程,每个线程往表中写1000条数据
这十个线程耗时900毫秒到1100毫秒不等
I3四核的个人电脑,仅做参考
#3
当然了,我的测试也有局限性,
写数据时,表结果越简单越好,也就是没有任何索引,计算列之类的,效率会高一些,
读数据时,尽可能根据具体情况加上合适的索引,效率会高一些,
这个就要求根据具体情况做衡量了,
如果是企业级应用,比如什么OA系统了,管理系统了之类的,
领导A批A部分的单子,领导B看B部门的文件,
这些系统基本上不会出现数据争用的现象,
基本上不会出现因为并发影响到使用的情况
除非用户量非常大(比如周一造成同时访问OA系统的人达到数千人甚至过万,可能出现应付不了并发的现象)
再就是系统设计的不合理
前段时间公司另外一个同事负责的OA系统,多说几千个用户,
然后周一早上容易迟到,这部分迟到的人就请别人在OA上给他们请假,
总的用户几千个,周一早上上班之前,
因为迟到同时请假的最多也就几十个,上百个,结果记录请假信息相关的表有ID重复的现象
这个竟然分析出来的问题是应付不了并发,真是可笑,
这些就是典型的例子,程度中不做任何控制,归结于数据库,是不合适的
写数据时,表结果越简单越好,也就是没有任何索引,计算列之类的,效率会高一些,
读数据时,尽可能根据具体情况加上合适的索引,效率会高一些,
这个就要求根据具体情况做衡量了,
如果是企业级应用,比如什么OA系统了,管理系统了之类的,
领导A批A部分的单子,领导B看B部门的文件,
这些系统基本上不会出现数据争用的现象,
基本上不会出现因为并发影响到使用的情况
除非用户量非常大(比如周一造成同时访问OA系统的人达到数千人甚至过万,可能出现应付不了并发的现象)
再就是系统设计的不合理
前段时间公司另外一个同事负责的OA系统,多说几千个用户,
然后周一早上容易迟到,这部分迟到的人就请别人在OA上给他们请假,
总的用户几千个,周一早上上班之前,
因为迟到同时请假的最多也就几十个,上百个,结果记录请假信息相关的表有ID重复的现象
这个竟然分析出来的问题是应付不了并发,真是可笑,
这些就是典型的例子,程度中不做任何控制,归结于数据库,是不合适的
#4
其实,之所以不需要程序加锁,是因为这些读 和 写 的锁,都是由sql server自动加的。
一般,在程序中,比如在windows中,多个线程,对一个全局变量,进行并发访问的时候,我们可以通过:
createmutex、createsemaphore等创建互斥体、信号量,这样在多线程访问全局变量时,就可以保证数据的一致性。
那么,在sql server中,当执行一个sql语句,而这个语句需要select 或者update数据的时候,由sql server自动对这个sql语句所需要读取的数据或者修改的数据,在处理数据的过程中,加锁,防止其他线程来修改。
一般,线程1在select数据的时候会加S锁,也就是共享锁,而线程2也在select同样的数据,也会加共享锁,这个时候,不会有阻塞的情况,因为读是可以共享的。
但如果线程1在读取数据,已经加了共享锁,而线程2要update,这个时候需要加上x锁,那么由于s锁和x锁,不兼容,就导致线程2被阻塞了。
一般,在程序中,比如在windows中,多个线程,对一个全局变量,进行并发访问的时候,我们可以通过:
createmutex、createsemaphore等创建互斥体、信号量,这样在多线程访问全局变量时,就可以保证数据的一致性。
那么,在sql server中,当执行一个sql语句,而这个语句需要select 或者update数据的时候,由sql server自动对这个sql语句所需要读取的数据或者修改的数据,在处理数据的过程中,加锁,防止其他线程来修改。
一般,线程1在select数据的时候会加S锁,也就是共享锁,而线程2也在select同样的数据,也会加共享锁,这个时候,不会有阻塞的情况,因为读是可以共享的。
但如果线程1在读取数据,已经加了共享锁,而线程2要update,这个时候需要加上x锁,那么由于s锁和x锁,不兼容,就导致线程2被阻塞了。
#5
加锁,肯定要加锁,但是程序上也要控制啊。3楼说的,那是数据唯一性问题。
#6
1、sql server会自动加锁,不需要通过程序来加锁的
2、是sql server自动加的读写锁,不需要程序来加锁。
3、c++,也是一样的
谢谢,这样我就放心了,我就怕我的程序会出莫名的问题
#7
对于查询,可以简单地理解为:在查询的数据上加了共享锁(在行级别加共享锁的同时,当然在表级别,也有意向共享锁,防止别人在你查询的时候把表给删除了,同理,在数据库级也有共享锁)
对于update语句,可以简单地理解为sqlserver先做查询,把要修改的记录给找到,然后在这个记录上做修改。
找记录的动作要加S锁,找到要修改的记录后会先加U锁,再将U锁升级成X锁。
至于锁加载那个级别(行锁,页锁,表锁等等),跟具体的表结构和索引类型有关
举个例子,如果按照ID更新,ID列上有索引,当更新执行中时,其他事物无法访问该ID的数据,包括读
如果表上ID上没有任何索引,加锁的就是整个表,导致整个表无法被访问
这些锁都是在事务提交之后释放的,这就要求,sql的执行后越早提交越好,
说白了还是跟sql执行效率和修改数据的量有关
我简单地测试过,用C#,同一张表,往里面写数据,开10个线程,每个线程往表中写1000条数据
这十个线程耗时900毫秒到1100毫秒不等
I3四核的个人电脑,仅做参考
感谢分享经验,非常有用
#8
纯读操作不会有什么影响,不过要看你是不是还有后续操作或者只有2个线程
#9
纯读操作不会有什么影响,不过要看你是不是还有后续操作或者只有2个线程
能说得再稍微具体一点不?假设我有10个线程?谢谢
#10
纯读操作不会有什么影响,不过要看你是不是还有后续操作或者只有2个线程
能说得再稍微具体一点不?假设我有10个线程?谢谢
#11
10个线程单纯读数据不影响,我是说你读了之后还要做什么事情?
纯读操作不会有什么影响,不过要看你是不是还有后续操作或者只有2个线程
能说得再稍微具体一点不?假设我有10个线程?谢谢
当然是不止读数据啊,光读数据我也知道不加锁都可以,每个线程都要更新数据的
#12
我目前的情况是有两个进程会同时读写同一张表,环境是.net 3.5或者4.0 + sql server 08,请问:
1.这样的情况要注意什么问题,需要加锁吗?如何加?
首先同意yupeigu的说法,程序上需要全局变量控制提交给SQL的变量.SQL层面上,如果是数据自动管理的锁,tzleo 回答了你的问题.
如果需要人为干预加锁,那么你可以使用Locking Hint, 请参考: http://technet.microsoft.com/en-us/library/ms172398.aspx
例子: 下面的Locking HINT保证了整个表在被某个transaction获得X锁后,完全被锁住.其它的 transaction不可以可以访问,修改该表.
Begin Trans
INSERT INTO table WITH ( TABLOCK )......
COMMIT Trans
2.如果我改用线程来做同样的事情,需要注意什么问题,需要加读写锁吗?
没看懂什么意思.
3.如果使用C++的话上述问题答案会不一样吗
程序层面,不懂
1.这样的情况要注意什么问题,需要加锁吗?如何加?
首先同意yupeigu的说法,程序上需要全局变量控制提交给SQL的变量.SQL层面上,如果是数据自动管理的锁,tzleo 回答了你的问题.
如果需要人为干预加锁,那么你可以使用Locking Hint, 请参考: http://technet.microsoft.com/en-us/library/ms172398.aspx
例子: 下面的Locking HINT保证了整个表在被某个transaction获得X锁后,完全被锁住.其它的 transaction不可以可以访问,修改该表.
Begin Trans
INSERT INTO table WITH ( TABLOCK )......
COMMIT Trans
2.如果我改用线程来做同样的事情,需要注意什么问题,需要加读写锁吗?
没看懂什么意思.
3.如果使用C++的话上述问题答案会不一样吗
程序层面,不懂
#13
我目前的情况是有两个进程会同时读写同一张表,环境是.net 3.5或者4.0 + sql server 08,请问:
1.这样的情况要注意什么问题,需要加锁吗?如何加?
首先同意yupeigu的说法,程序上需要全局变量控制提交给SQL的变量.SQL层面上,如果是数据自动管理的锁,tzleo 回答了你的问题.
如果需要人为干预加锁,那么你可以使用Locking Hint, 请参考: http://technet.microsoft.com/en-us/library/ms172398.aspx
例子: 下面的Locking HINT保证了整个表在被某个transaction获得X锁后,完全被锁住.其它的 transaction不可以可以访问,修改该表.
Begin Trans
INSERT INTO table WITH ( TABLOCK )......
COMMIT Trans
2.如果我改用线程来做同样的事情,需要注意什么问题,需要加读写锁吗?
没看懂什么意思.
3.如果使用C++的话上述问题答案会不一样吗
程序层面,不懂
非常感谢,帮了大忙了