事务处理只在你需要提交时才使用,当你打开数据集,在编辑时不需锁定,这样其他用户就可以同时使用.举个例子:
...
procedure edit;
begin
adoquery1.open;
adoquery1.edit;
end;
procedure save;
begin
adoconnection.beginstran;
try
adoquery1.applyupdates;
adoconnection.commition;
except
adoconnection.rollback;
end;
end;
不要一进入窗体便
adoconnection.beginstran;
...
procedure edit;
begin
adoquery1.open;
adoquery1.edit;
end;
procedure save;
begin
adoconnection.beginstran;
try
adoquery1.applyupdates;
adoconnection.commition;
except
adoconnection.rollback;
end;
end;
不要一进入窗体便
adoconnection.beginstran;
lock 或 record lock, 都可以让多人同时更新的.
例如Interbase有Tranactional versioning (事务版本) 机制, 即是每事务
都有自己独立的序号, 数据库是记着最新的序号, 就算两人同时更新, 该序号都
是不同的, 都某人先更新数据了, 当前的数据库上的序号便更新了. 之後, 迟了的那个用户, 当要update数据时便会发觉他的序号已迟了, 而报错. 因些这个序
号便隔离了多用所更新的数据但不用预先把数据上锁.所以当用於多人同时更新的数据时, 便应少用 cache update, 最好每次只下载或
上载单一个纪录便最保险了.
begin
adoconnection.beginstran;
try
adoquery1.applyupdates; //这条语句有什么作用,以前我没用过,是不是先更新一下adoquery1里的内容
adoconnection.commition;
except
adoconnection.rollback;
end;
end;好像没这么简单吧, 这些概念我还没太理解
select ...for update;
这样,在这个事务没有结束之前,其它有“for update”的select语句就会等待。
注意:一定要起用事务。
adoquery-->连接到adoconnection,
datasource连接 adoquery1,放一个dbgrid,控件,再放一个增加,一个修改 ,一个删除按钮.dbgrid的datasorce连接到datasource1, 我在form1的create事件里 with adoquery1 do
begin
active:=false;
sql.clear;
sql.add('select * from table1');
active:=True;
end;显示正常,1。点击添加操作; procedure Tform1.button1click(sender:object); //添加;
begin
Form2:=Tform2.create(application);
Form2.option:=0; //表示添加;
adoquery1.append;
Form2.showmodal;
end; procedure Tform1.button1click(sender:object); //添加;
begin
Form2:=Tform2.create(application);
Form2.option:=1; //表示修改;
adoquery1.edit;
Form2.showmodal;
end;
进入Form2后,(我在form2放了两个 dbedit用于显示数据.编辑数据);另外还有一个确定按钮, 一个取消按钮.Public
option:integer;Procedure Tform2.button1click(sender:object); 确定
begin
Try
Adoconnection.Beginstran;
ADOQUERY1.POST;
Adoconnection.commit;
except
showmessage('删除不成功'); 1.//这里的数据库错误类型是怎样确定的。
Adoconnection.rollback;
end;
end;问题:
不知道我上面写的是否合理,请大家指教。 我在单用户环境操作是没有问题的。
但当两个用户(我故意这么测试, A用户点击该模块的Form1增加按钮, B用户也点击该模块的增加按钮, 这样当其中一个用户A先点击Form2“确定”
保存成功,
但是当B用户点击“确定”按钮时, A用户其实已经修改了数据,B用户此时操作将不成功, 事务回滚。
?这个事务回滚的原因是什么。语句怎样写。大家是怎样控制的。
其实在提交事务时如果出错?ADOConnection是会返回错误的.怎么返回你们查手册吧.
考虑在多用户环境下操作,我把结果存放在临时表(其实可以不用临时表,直接用adoquery.sql('select ..') active:=True,就可以把结果显示在dbgrid里面,但我为了让dbgrid里面能显示100条记录, 如果查询结果没有100条则添加 100-adoquery1.recordcoutn条空记录在后面)。 这样查询的结果保证dbgrid会显示100条记录, 用临时表对服务器有什么影响,客户多的情况下,会不会现并发情况,(我昨天看一篇贴子说本地临时表都是独立创建的。并不受影响)所以我才用了临时表。 不知是否合理。
2、同意menliwxj(有缘)的建议,事务处理只在你需要提交时才使用,当你打开数据集,在编辑时不需锁定,这样其他用户就可以同时使用.
3、对sql server来说,如果没有改变设置,“当两个用户同时修改一条记录”这种情况实际是有先后的,前一个事务会给记录加更新锁,后一个事务只能等待前一个事务完成才能操作这条记录。而“一个用户修改一条记录而另一个用户确删掉了这条记录。” 也是有先后的,如果修改再前,修改加更新锁,完成修改后才能删除;如果删除再前,那修改的进程会找不到修改的记录而报错。
Procedure Tform2.button1click(sender:object); 确定
begin
Try
Adoconnection.Beginstran;
ADOQUERY1.POST;
Adoconnection.commit;
except
showmessage('删除不成功'); 1.//这里的数据库错误类型是怎样确定的。
Adoconnection.rollback;
end;
end;我这样测试
在提交的时候才锁定记录, 所以每个用户都可以编辑。
当A用户在编辑10号记录时, 还未提交 正在进行中, B用户此时打开10号记录也进行编辑, 此时A按了保存按钮,执行了上面这段代码,保存成功, 而B用户也可以操作这条记录,这是属于行锁吗?点保存按钮时确出错了。键值未定义。是不是你讲的"前一个事务会给记录加更新锁,后一个事务只能等待前一个事务完成才能操作这条记录"这种情况.
当用户要编辑记录时 先检查刚才那个表A 如果有此记录则显示 'XXX正在修改'
如果没有人在修改则添加此用户及表的关键字
我一开始是这么想的。 那这样就属于表锁定了。范围太大了。
如果有30个用户在修改表, 大家都得等,不是很好。 对不对?