sql server 自动提交问题

来源:百度知道 编辑:UC知道 时间:2024/06/16 22:53:11
以下的代码为什么没有实现我想要的结果,100的倍数时提交一次

set implicit_transaction on;

drop table angusTest_tbl;--删除表
--创建表
create table angusTest_tbl(
id int primary key,--用来记录行数
now datetime --时间
);
--删除存储过程
drop procedure angusTest_proc
--建立存储过程
create procedure angusTest_proc
as
begin
declare @v_timenow datetime
declare @i int
set @i=1

while 2>0
begin
select @v_timenow=getDate() --得到当前时间
insert into angusTest_tbl(id,now) values(@i,@v_timenow);
if @i%100=0 --i是100的倍数时,提交一次
begin
commit
end
WAITFOR DELAY '00:00:02' --每一次循环,停2秒
set @i=@i+1; --自增
end
end

--执行存储过程
begin
exec angusTest_proc
end
--查找表内容
select * from angusTest_tbl;
问题我解决了,
use demo;
SET IMPLICIT_TRANSACTIONS off;
drop table angusTest_tbl;--删除表

因为每一次循环,都执行了:insert into angusTest_tbl,而这一句就是一个完整的操作(隐性事务),所以数据立即就写入了数据表。

单纯的一个 commit 语句并没有什么意义。
只有在显式事务中,commit 与对应的 BEGIN TRANSACTION 语句一起作用才有意义。

你要批量插入,我建议用一个临时表,先把数据写到临时表中,到了时机,再批量插入主表。这样实现很快很简单 ^-^

因为你要用事务来做的话,在这100条数据写入的过程中(Commit 之前的200秒,时间相当长)这个表中的这些数据是锁定的,如果有其他用户或程序查到它们,就会被堵塞,如此很可能引起大遍的堵塞,最终会出现数据库死锁。

其实在Commit之前,数据已写入,只是未Commit,所以其他程序s可能会试图它们,比如 select * from angusTest_tbl,但访问却不能立即成功,于是访问者会进入等待状态,等待Commit之后才能真正读出这些数据。
也就是说,在存储过程运行过程中,select * from angusTest_tbl 是查不出数据来的,处于无响应状态。(现在能查,是因为还没有写成100条一组的事务)

当然,你可以这样 select * from angusTest_tbl with nolock 来读“脏数据”,但是一般不建议。

希望能对你有帮助。

set autocommit=false