Delphi数据库操作关于事务怎么写比较好?

ooolinux 2015-07-30 01:39:38
引用
看到有人说:
在beforepost事宜中begintran在afterpost事宜中committran在posterror事宜中rollback,当然,不是哪么绝对


但是,如何避免并发时有其它事务已经开始了导致事务失败?

如果不是Post而是UpdateBatch或者ExecSQL,这种方式对应beforepost、afterpost和posterror事件的是什么?

如果用try、catch、finally,代码怎么写比较好?
...全文
541 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
ooolinux 2015-08-07
  • 打赏
  • 举报
回复
引用 11 楼 lyhoo163 的回复:
事务处理,只在一个客户端操作。 至于众多客户端,写操作数据库同一个表、字段,是按先后次序进行的。相与不干扰,但有这种情况,客户端读取的数据,已经被其它客户端修改。具体数据,以最后一次写入为主。
数据库中并发事务的操作是交叉执行的,交叉执行是否正确取决于可串行性。如果并发执行的所有事务都遵守两段锁协议,则对这些事务的任何并发调度策略都是可串行化的。(书上说的) 书上也说三级封锁协议可以解决丢失修改、读“脏”数据和不可重复读问题。
英年渐肥 2015-08-07
  • 打赏
  • 举报
回复
字段的数据值肯定取决与最后的更新。具体事务的执行由数据库控制。不过在程序中触发显式事务有几种方式。需要考虑组件和数据库的匹配。数据组件如adoquery一般可以直接触发,尔dataprovider也可以触发,个人喜欢使用dataprovider方式触发。使用sql代码方式触发效率低。
sxper 2015-08-06
  • 打赏
  • 举报
回复
事务的出现 就是为了解决多用户冲突操作同一记录的。 放心没问题的。我们这里医保也用的。医保数据大了吧。
yaliks 2015-07-31
  • 打赏
  • 举报
回复
你考虑的太多了。这些事是数据库会去完成的事情。不用你考虑。你可以这么理解。大家排好队。先来后到。一个人进去后关上门。别人都在门外面。等他处理好事情出来了。下一个进去。所以不会冲突。
lyhoo163 2015-07-31
  • 打赏
  • 举报
回复
事务处理,只在一个客户端操作。 至于众多客户端,写操作数据库同一个表、字段,是按先后次序进行的。相与不干扰,但有这种情况,客户端读取的数据,已经被其它客户端修改。具体数据,以最后一次写入为主。
ooolinux 2015-07-31
  • 打赏
  • 举报
回复
引用 8 楼 yaliks 的回复:
你考虑的太多了。这些事是数据库会去完成的事情。不用你考虑。你可以这么理解。大家排好队。先来后到。一个人进去后关上门。别人都在门外面。等他处理好事情出来了。下一个进去。所以不会冲突。
所以才要事务阿
ooolinux 2015-07-31
  • 打赏
  • 举报
回复
引用 7 楼 lyhoo163 的回复:
回复3楼,在三层中,每个客户端各自在服务器创建独立的数据库的连接,以及相关的方法。所以各自的事务处理是不干涉的。
我的意思是,很多个相同的客户端同时运行,并发访问数据库服务器中的同一个数据库同一个表甚至同一条记录同一个字段。
缘中人 2015-07-30
  • 打赏
  • 举报
回复
客户端之间互不影响。这个事务是ado的,不是数据库的。
ooolinux 2015-07-30
  • 打赏
  • 举报
回复
引用 1 楼 lyhoo163 的回复:
1、数据库的事务处理,是数据库的专有,只有该数据支持事务处理,Delphi才能调用该事务处理。 2、事务处理的机制是,提供若干个SQL语句,供同时一次性全部被执行。 3、事务处理有一个回滚机制,只要需要被的一个(含以上)语句未被执行,或执行出现错误,取消所有的(已执行)SQL语句。 以Delphi的 TADOConnection为例,可以设计一个事务处理函数:
function TTServer.RunTranscation(const SQL1, SQL2, SQL3, SQL4: WideString;
  out err: WideString): WordBool;
begin
  Result:=False;
  try
    ADOCon.BeginTrans;                // 开始事务
    if SQL1<>'' then                  // 确定SQL有效
      ADOCon.Execute(SQL1);
    if SQL2<>'' then                  
      ADOCon.Execute(SQL2);
    if SQL3<>'' then                  
      ADOCon.Execute(SQL3);
    if SQL4<>'' then                  
      ADOCon.Execute(SQL4);
    ADOCon.CommitTrans;               // 提交事务
    Result:=True;
  except
    on E:Exception do
    begin
      ADOCon.RollbackTrans;           // 事务回滚
      err:=E.Message;
    end;
  end;
end;
对于C/S架构,很多个客户端同时运行,有的时候ADOCon.BeginTrans的时候,数据库已经在一个事务进行过程中了,这个时候BeginTrans就失败了。如何确保每一个客户端都能成功进行事务呢?
lyhoo163 2015-07-30
  • 打赏
  • 举报
回复
回复3楼,在三层中,每个客户端各自在服务器创建独立的数据库的连接,以及相关的方法。所以各自的事务处理是不干涉的。
lyhoo163 2015-07-30
  • 打赏
  • 举报
回复
1、数据库的事务处理,是数据库的专有,只有该数据支持事务处理,Delphi才能调用该事务处理。 2、事务处理的机制是,提供若干个SQL语句,供同时一次性全部被执行。 3、事务处理有一个回滚机制,只要需要被的一个(含以上)语句未被执行,或执行出现错误,取消所有的(已执行)SQL语句。 以Delphi的 TADOConnection为例,可以设计一个事务处理函数:
function TTServer.RunTranscation(const SQL1, SQL2, SQL3, SQL4: WideString;
  out err: WideString): WordBool;
begin
  Result:=False;
  try
    ADOCon.BeginTrans;                // 开始事务
    if SQL1<>'' then                  // 确定SQL有效
      ADOCon.Execute(SQL1);
    if SQL2<>'' then                  
      ADOCon.Execute(SQL2);
    if SQL3<>'' then                  
      ADOCon.Execute(SQL3);
    if SQL4<>'' then                  
      ADOCon.Execute(SQL4);
    ADOCon.CommitTrans;               // 提交事务
    Result:=True;
  except
    on E:Exception do
    begin
      ADOCon.RollbackTrans;           // 事务回滚
      err:=E.Message;
    end;
  end;
end;
ooolinux 2015-07-30
  • 打赏
  • 举报
回复
另一个问题: 一种最简单的情况,数据库中有一个表A,一个字段TotalGames,游戏客户端程序每次玩了一局游戏,要给TotalGames加一。 在BeginTrans、Post或者UpdateBatch或者ExecSQL、CommitTrans三条语句中,如果成功的话,哪一条语句以后数据库锁住表,哪一条语句后数据库释放表呢?
ooolinux 2015-07-30
  • 打赏
  • 举报
回复
引用 4 楼 ksrsoft 的回复:
客户端之间互不影响。这个事务是ado的,不是数据库的。
ado不只是访问数据库的一种封装一种桥梁吗?事务不是数据库的,怎么讲?大量客户端以事务方式并发访问数据库难免冲突吧?

2,497

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 数据库相关
社区管理员
  • 数据库相关社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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