多条insert/update语句,多人同时提交是否会造成死锁!马上给分!

hrbqian0 2006-01-03 08:44:39
多个操作员在不同的机器同时点击按钮,执行多条insert/update语句
同时提交时sqlserver怎么处理,是并发还是处理一个操作员后再处理其他人员?
...全文
913 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
尽量不要多条语句一起提交!!!UPDATE语句后面可以INSERT, 但INSERT 后面不能用UPDATE,如果想UPDATE,必须在INSERTR提交后才能UPDATE!!UPDATE属于独占锁!!
guomaomao1981 2006-01-05
  • 打赏
  • 举报
回复
把事务弄成自动提交的,死锁现象会大大减少。然后sql 语句中写上 using 事务名称(自动提交)。
hygougou 2006-01-04
  • 打赏
  • 举报
回复
sql server 对并发的处理由它本身的锁控制,貌似并发,其实有等待排队的现象,只不过时间间隔短,所以并发数很多的时候,还是得进行人工锁设计并发数中度多的时候建议用pb的数据窗口,因为其本身带有锁机制,可以有效的处理并发问题
------------------------------
参考以下对锁的例程描述,具体可到sql server版问,或者找有关这方面的书读读

------------------------------
--建立测试表的语句
CREATE TABLE 帐户表
(
帐号 CHAR(4),
余额 INT
)
GO
INSERT 帐户表
SELECT 'A',100
UNION ALL
SELECT 'B',200

1、排它锁测试

--在第一个连接中执行以下语句
BEGIN TRAN
UPDATE 帐户表 SET 余额=300 WHERE 帐号='A'
WAITFOR DELAY '00:00:10' --等待10秒
COMMIT TRAN

--在第二个连接中执行以下语句
BEGIN TRAN
SELECT * FROM 帐户表 WHERE 帐号<>'A'
COMMIT TRAN

/**说明:
若同时执行上述两个语句,只要第一句更新的行数大于零,则第二句必须等待10秒。
疑问:如果帐户A的余额本来就是300,第二个连接也会立即返回
如果连接二中把SELECT * FROM 帐户表 改成 SELECT * FROM 帐户表 WITH ( NOLOCK),读取任何记录,都不需要等待
或者在连接二使用READ UNCOMMITTED隔离级别也可

执行语句一时,系统会在帐户表上使用TABLOCKX排它锁。该锁可以防止其它事务读取或更新表,并在语句或事务结束前一直持有。
NOLOCK选项:该选项不发出共享锁,并且不要提供排它锁。当此选项生效时,可能会读取未提交的事务或一组在读取中间回滚的页面。有可能发生脏读。仅应用于 SELECT 语句。
**/


2、
--在第一个连接中执行以下语句
BEGIN TRAN
SELECT * FROM 帐户表 WHERE 帐号='A'
WAITFOR DELAY '00:00:10'
COMMIT TRAN

--在第二个连接中执行以下语句
--A句
UPDATE 帐户表 SET 余额=10 WHERE 帐号='A' --要等待10秒,从而避免非重复读
--B句
UPDATE 帐户表 SET 余额=10 WHERE 帐号='B' --不需要等待,立即执行

--如果想在连接一中锁住整个表,不允许其他事务更新表中任何记录,但可以读取记录,可使用HOLDLOCK选项,即(HOLDLOCK 等同于 SERIALIZABLE)
BEGIN TRAN
SELECT * FROM 帐户表 WITH(HOLDLOCK) WHERE 帐号='A'
WAITFOR DELAY '00:00:10'
COMMIT TRAN

--如果想在连接一中锁住整个表,不允许其他事务更新表中任何记录甚至读取表中任何记录,可使用TABLOCKX选项,即(SET TRANSACTION ISOLATION LEVEL SERIALIZABLE做不到)
BEGIN TRAN
SELECT * FROM 帐户表 WITH(TABLOCKX) WHERE 帐号='A'
WAITFOR DELAY '00:00:10'
COMMIT TRAN


--如果想在连接一中不锁定表,允许其他事务更新表中任何行,使用NOLOCK选项,即
BEGIN TRAN
SELECT * FROM 帐户表 WITH(NOLOCK) WHERE 帐号='A'
WAITFOR DELAY '00:00:10'
COMMIT TRAN


SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
BEGIN TRAN
SELECT * FROM 帐户表 WITH (ROWLOCK) WHERE 帐号='A'
WAITFOR DELAY '00:00:10'
COMMIT TRAN



3、死锁测试
--增设 帐户表_2
CREATE TABLE 帐户表_2
(
帐号 CHAR(4),
余额 INT
)
GO
INSERT 帐户表_2
SELECT 'C',100
UNION ALL
SELECT 'D',200


--在第一个连接中执行以下语句
BEGIN TRAN
UPDATE 帐户表 SET 余额=3 WHERE 帐号='A'
WAITFOR DELAY '00:00:10'
UPDATE 帐户表_2 SET 余额=3 WHERE 帐号='C'
COMMIT TRAN

--在第二个连接中执行以下语句
BEGIN TRAN
UPDATE 帐户表_2 SET 余额=4 WHERE 帐号='C'
WAITFOR DELAY '00:00:10'
UPDATE 帐户表 SET 余额=4 WHERE 帐号='A'
COMMIT TRAN

--删除测试表
DROP TABLE 帐户表,帐户表_2

--同时执行,系统会检测出死锁,第一个连接的事务可能正常执行,SQL Server 终止第二个连接的事务(不涉及超时)。
--如果没有出现死锁,则在其它事务释放锁之前,请求锁的事务被阻塞。
--LOCK_TIMEOUT 设置允许应用程序设置语句等待阻塞资源的最长时间。

4、更新数据时候允许进行插入
5、插入数据时不允许更新\读取
cbz0660 2006-01-04
  • 打赏
  • 举报
回复
同意樓上的
Methodor 2006-01-04
  • 打赏
  • 举报
回复
是否会造成死锁看具体情况了,一般来说肯定有可能造成死锁,至于如何规避死锁则需要按照实际需求和流程来做处理了
yxl0173 2006-01-04
  • 打赏
  • 举报
回复
是否会造成死锁看具体情况了,一般来说肯定有可能造成死锁,至于如何规避死锁则需要按照实际需求和流程来做处理了

hrbqian0 2006-01-03
  • 打赏
  • 举报
回复
假设其中的一部分是:每个操作员往a表中插入一条数据,
并在a表计算最大流水号回写到此条数据中,如果多人同时操作,结果能对吗?
insert into a (t1) values (:ll_t1); //t1为主键
update a set lsh=(select max(lsh) from a) where t1=:ll_t1;


wfliu 2006-01-03
  • 打赏
  • 举报
回复
对事务的理解还是不很清楚,

有7个操作员从7台终端提交多条insert/update语句,对服务器而言,是7个事务,只要处理好每个事务的完整性,就不会造成错误。

对程序员来说,只是一个过程,在这个过程中,你不可能等待其他操作员动作,你要保证你自己数据的一致性和事务完整性,就可以了。

从编程方面来说,多条insert/update 和 commit 语句之间要采用尽量少的代码,将所有数据准备工作在insert/update之前准备好,以缩短数据库执行时间,避免死锁。
hrbqian0 2006-01-03
  • 打赏
  • 举报
回复
如果每个操作员update的内容不一致,与insert不相关。
还存在多个insert,一并提交会有问题吗,会死锁?
li_d_s 2006-01-03
  • 打赏
  • 举报
回复
数据窗口提交的话,可以通过where clause来控制,如果是insert应该不会造成死锁的,但是最好还是及时提交
hrbqian0 2006-01-03
  • 打赏
  • 举报
回复
语句是对多个表操作,有的insert,有的update,
如果成功,一并提交,否则回滚,一个都不能执行!
如果3个操作员同时执行可能不会有问题,
多于7个操作员恐怕会出现问题!
lzheng2001 2006-01-03
  • 打赏
  • 举报
回复
修改后马上COMMIT的话可以防止死锁
hrbqian0 2006-01-03
  • 打赏
  • 举报
回复
update table1 set t1=1,t2=2

update table1 set t1=1;
update table1 set t1=2;
在有其他人员正在插入table1数据时,执行结果不同!
为什么?
在执行上面的语句时就不是先后顺序,更新了部分插入数据,下面的是!
wangxichen 2006-01-03
  • 打赏
  • 举报
回复
有先后次序的

如果操作员所操作的是相同的数据,
后面操作员的修改会覆盖前面操作员的

如果前面的操作员将数据删除了,
后面的操作员再保存时就会因为找不到保存的记录出现数据库错误
也就是所谓的“脏读”

1,079

社区成员

发帖
与我相关
我的任务
社区描述
PowerBuilder 相关问题讨论
社区管理员
  • 基础类社区
  • WorldMobile
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧