有三个存储过程,p1:使表1的rno加1;p2:使表2的rid加1;p3:更新表3的num(库存数量)在VB里,首先启动事务,“exec p1 → insert into c_m”(步骤一),然后循环“exec p2 → insert into c_d → exec p3”(步骤二),循环结束后结束事务,如果中间有出错,则回滚事务。疑问1:只有一个用户在操作,在第2次执行步骤二的p3时出错,事务回滚:发现所有的insert into、p2和p3都有回滚,唯独没有回滚p1更新的rno,请问这是怎么回事?疑问2:假设有多个用户同时进行此操作,某个用户在第N次执行步骤二的p3时出错,请问这样的情况是怎么回滚的,是不是从启动事务开始就会锁定表1、表2、表3?疑问3:事务回滚是会回滚存储过程或函数里的所有操作?
谢谢!
谢谢!
请问如何设置检查点,我是用SQL2000
vb的和sp的
CREATE PROCEDURE p1(@rno VARCHAR(10) OUTPUT)
AS
BEGIN
SET NOCOUNT ON
-- 表1的rno,VARCHAR,只有一行,值的格式ymmddxxxx(前5位年月日,后4位序号)
DECLARE @a VARCHAR(10), @b VARCHAR(10
SELECT @a=RIGHT(CONVERT(VARCHAR(6),GETDATE(),12),5)+'0001'
SELECT @b=rno+1 FROM 表1
IF @a>@b
SELECT @rno=@a
ELSE
SELECT @rno=@b IF @b IS NULL
INSERT INTO 表1(rno) VALUES (@rno)
ELSE
UPDATE 表1 SET rno=@rno SET NOCOUNT OFF
END
-------------------------------------------------------------CREATE PROCEDURE p2(@rid VARCHAR(10) OUTPUT)
AS
BEGIN
SET NOCOUNT ON
-- 表2的rid,CHAR,只有一行,值只记录序号 SELECT @rid=@rid+1 FROM 表2 IF @rid IS NULL
INSERT INTO 表2(rid) VALUES (@rid)
ELSE
UPDATE 表2 SET rid=@rid SELECT @result=1 SET NOCOUNT OFF
END
-------------------------------------------------------------CREATE PROCEDURE p2(@sid VARCHAR(25), @sale_num NUMERIC(15,5), @result BIT=0 OUTPUT)
AS
BEGIN
SET NOCOUNT ON
-- 表3用于保存库存数量,sid:品种ID,num:库存数量
IF NOT EXISTS (SELECT num FROM 表3 WHERE sid=@sid AND num>@sale_num)
RETURN UPDATE 表3 SET num=num-@sale_num WHERE sid=@sid SET NOCOUNT OFF
END' VB代码
' 表4 销售主表 表5 销售副表
' objcn as Connection,objcmd as Command On Error GoTo Err_Proc Dim strrno As String, strrid As String, i As Integer objcn.BeginTrans
objcmd.CommandType = adCmdStoredProc
objcmd.CommandText = "p1"
objcmd.Execute strno=objcmd.Parameters("@rno") objcn.Execute "INSERT INTO 表4 (rno, ...) VALUES ('" & strno & "' ...)" For i=1 To VSFlexGrid1.Rows-1
objcmd.CommandType = adCmdStoredProc
objcmd.CommandText = "p2"
objcmd.Execute
strrid=objcmd.Parameters("@rno") objcn.Execute "INSERT INTO 表5 (rno, rid, sid ...) VALUES ('" & strno & "' ...)" objcmd.CommandType = adCmdStoredProc
objcmd.CommandText = "p3"
objcmd.Parameters("@sid")=VSFlexGrid1.TextMatrix(i, VSFlexGrid1.ColIndex("sid"))
objcmd.Parameters("@sale_num")=VSFlexGrid1.TextMatrix(i, VSFlexGrid1.ColIndex("sale_num"))
objcmd.Execute If objcmd.Parameters("@result")=0 Then
MsgBox "更新库存失败!"
objcn.RollbackTrans
End If
Next objcn.CommitTrans
MsgBox "单据已经保存!"
Exit SubErr_Proc:
objcn.RollbackTrans
写了事务就表示b已经完成.已经修改记录了..在a中出错.将不会回滚资料了.
因为现在手头没有代码,这些是现写的,大体就这样,请各位帮忙看一下。
我现在比较不明白就是多次执行p3后,如果也有其他用户在进行类似操作,那这个库存数量是如何回滚的。
create table tb (id int)
go
create procedure outproc as
begin
begin transaction OutOfProc
exec inproc
rollback transaction OutOfProc
end
go
create procedure inproc as
begin
begin transaction InOfProc
insert into tb select 100
commit transaction InOfProc
select * from tb
end
go
exec outproc
go
select * from tb
drop table tb
drop procedure outproc,inproc
/*
id
-----------
100(1 行受影响)id
-----------(0 行受影响)
*/
新建一表test,而有一列ca,值为0
同时打开两个程序,A勾选复选框,结束时会回滚,B结束时提交,A先开始,当A弹出“暂停”对话框时B出现没有响应,点确定后发现ca的值是2
这好像说明SQL会锁定更新的表直至事务提交或回滚--附事件探查器------------
set implicit_transactions on
go
UPDATE test SET ca=ca+1 --回滚
go
set implicit_transactions on
go
UPDATE test SET ca=ca+1 --回滚
go
UPDATE test SET ca=ca+1 --提交
go
UPDATE test SET ca=ca+1 --提交
go
IF @@TRANCOUNT > 0 COMMIT TRAN
go
IF @@TRANCOUNT > 0 ROLLBACK TRAN 为什么A回滚是在B的提交之后呢??而且值还是2
go
----------------------------------
Dim objConn As Connection
Set objConn = New Connection
objConn.ConnectionString = "Provider=SQLOLEDB.1;Password=;Persist Security Info=True;User ID=sa;Initial Catalog=test;Data Source=(local)"
objConn.Open
objConn.BeginTrans
If CBool(Check1.Value) Then
objConn.Execute "UPDATE test SET ca=ca+1 --回滚"
MsgBox "暂停"
objConn.Execute "UPDATE test SET ca=ca+1 --回滚"
objConn.RollbackTrans
objConn.Close
MsgBox "回滚"
Else
objConn.Execute "UPDATE test SET ca=ca+1 --提交"
objConn.Execute "UPDATE test SET ca=ca+1 --提交"
objConn.CommitTrans
objConn.Close MsgBox "完成"
End If