事务中的网络故障(100分)

  • 主题发起人 主题发起人 popeye
  • 开始时间 开始时间
P

popeye

Unregistered / Unconfirmed
GUEST, unregistred user!
server:unix open server+informix online
client:win98
BDE数据源:ODBC的informix driver,sqlthroughmode:not shared

database.starttransaction;
try
...
query1.add('insert into table ...');
query1.execsql;
...
query2.add('insert into table ...');
query2.execsql;
except
database.rollback;
end;
database.commit;

当query1.execsql执行成功后,query2由于参数错误execsql发生异常时
能够执行database.rollback,程序退出后查看数据库证明回滚成功.

当query1.execsql执行成功后,在query2.execsql之前showmessage('suspend')
暂停,然后拔掉网络线模拟网络故障,死机.结束程序后查看数据库发现
query1的插入生效.像这种情况如何能保证数据的完整性?
 
语句database.commit;的位置不对,应该放在except的前面。

database.starttransaction;
try
...
query1.add('insert into table ...');
query1.execsql;
...
query2.add('insert into table ...');
query2.execsql;
database.commit;
except
database.rollback;
end;

 
》拔掉网络线模拟网络故障,死机.结束程序后查看数据库发现query1的插入生效

难道是informix特有?oracle不会。而且你有设置read dirty还是read commit的,
如果别的客户是read dirty那么它可读其他进程未提交的数据,如果超时过了,
或者你重新起数据库,看看,应该query1的修改会被回滚了
 
1.agree with yck 这样换下位置,可针对第一种情况.
2.不合理,不合理.
试试Pipi.的方法吧,设置一下database1.TransIsolation属性

 
修改一下做法 :)
...
query1.add('insert into table ...');
...
query2.add('insert into table ...');

database.starttransaction;
try
query1.execsql;
query2.execsql;
database.commit;
except
database.rollback;
end;
减少错误率。
 
我同意 yck 的做法,把COMMIT 放在TRY中,而不是EXCEPT 之后。
 
多人接受答案了。
 
后退
顶部