三层,如何进行事务处理? ( 积分: 50 )

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

ppqingyu

Unregistered / Unconfirmed
GUEST, unregistred user!
MSSQL五个表,相互有关联,每个表除了主表是一条记录外,其他表有数条不等的记录,用存储过程,一次提交一条记录,因需要保持其数据的完整性,一旦提交当中一个表的任一条记录出错,当次全部回滚,但是TClientDataSet没有事务,在服务器端如何处理?
在客户端用SQL语句进行事务也是不行,偶尔会出现这个错误
Rollback transaction请求没有对应的bedin transaction
 
如果用Com+的话, 你可以不用关心事务, 因为服务端已经帮助你管理了.出错的话, 服务端自动rollback
当然你也可以自己控制, 不过自已得查查资料. 李维建议一般情况下不要自己处理.
 
TO 3868474:
因为是主从表提交,从表有多条记录,无论你是用什么都好,你都需要通知系统,你从什么时候开始是事务开始,什么时候是事务结束吧?
要不系统不是当你是提交了多次的单表?
 
我也看过李维所说的MIDAS自动事务,但是都是一个TClientDataSet的,没有见过提交多个存储过程的.
 
不用, 当你开始执行时就开始了事务. 当你断开连接时系统提交事务.
前提是Com+, 所以用完应该及时断开连接. 这是我的理解. 不知是否有偏差. 还要你自己验证
 
断开连接一次,就是提交事务一次?
 
应该是吧.以前做过一个拔号数据传输, 用的就是Com+, 当时就是这样的.
 
给我一个例子看看吧.
lnming@yeah.net
 
无忧站网络——专业提供虚拟主机、域名注册、网页制作、LOGO制作、网站推广等服务。
更多空间详情请登陆 http://www.51zhan.com
 
看看李维的<分布式多层应用开发>那一本书吧.
 
我看过,但是看不太明白,而且我用的是ADO
 
1、首先中间层及数据库服务器应该支持分布式事务
2、中间层要支持事务,SetComplete提交,SetAbort回滚
 
在这里,首先谢谢大家的光顾和指点.第二,大家都直接说说你们实现的方法吗?草草几句,你们也知道这样的实用性是了了无几的.
 
多表中,如果里面亦有明细表,那样的话,直接使用李维所说的多表数据更新,好像行不通,因为在从表新增一条数据,那么主表亦增一条数据,不能主表增一条,从表多条.
 
三层的事务, 不应该是你客户端关心的. 被中间层业务对象调用就行了.
中间层的业务对象, 事务也不是你关心的, 交给一个专门的数据管理层处理(持久层)...
你只需调用, 有问题, 持久层返回业务对象, 业务对象借助日志对象,生成服务器日志记录, 并返回业务错误给客户端......
 
这个持久层如果写?你是如何一次性将数据打包提交到中间层的(你毕竟是多表,而且是主从明细表)?如果不是一次性,那你又是如果控制那个提交数据的完整性(又回到了事务了[:(!])
 
对wu_yanan2003的回答比较感兴趣。。。
 
数据访问层简单实现,就是对select , Update, insert的包装. 只需要获得一个数据连接conn.只做数据操作. 用多态
TDataPerWapper = class(TPersistentAdapter)
function SelectDataSet(const sql: String): TADODataSet;
function SelectVOList(const pTO: TDataTransferObject): TDataTransferObjectList;
overload;
virtual;
safecall;
function SelectVOList(const pTO: TDataTransferObject;
filtrateSQL: String): TDataTransferObjectList;
overload;
virtual;
safecall;
返回数据集, TLIST列表.
新增,删除,插入:
function ExecRDMDS(const pSQL: String): Boolean;
function InsertRDMDS(const pTO: TDataTransferObject): Boolean;
overload;
virtual;
safecall;
function InsertRDMDS(const pTOList: TDataTransferObjectList): Boolean;
overload;
virtual;
safecall;
function InsertRDMDS(const pTOStringList: TStringList): Boolean;
overload;
virtual;
safecall;
再借助一个生成SQL语句的类:
TDAOAdapter = class(TPersistentAdapter)
public
function GetFldName(tmpFld: String): String;
function IsKeyFld(tmpFld: String): Boolean;
function getKeySQLString(Const pTO: TDataTransferObject): String;
function getMaxCountString(Const pTO: TDataTransferObject): String;
function getSearchSQLString(Const pTO: TDataTransferObject): String;
overload;
function getSearchSQLString(Const pTOList: TDataTransferObjectList): TStringList;
overload;
function getInsertSQLString(Const pTO: TDataTransferObject): String;
overload;
function getInsertSQLString(Const pTOList: TDataTransferObjectList): TStringList;
overload;
function getUpdateSQLString(Const pTO: TDataTransferObject): String;
overload;
function getUpdateSQLString(Const pTOList: TDataTransferObjectList): TStringList;
overload;
function getUpdateSQLString(Const pTO: TDataTransferObject;
filtrateSQL: String): String;
overload;
function getUpdateSQLString(Const pTOList: TDataTransferObjectList;
filtrateSQL: String): TStringList;
overload;
function getDeleteSQLString(Const pTO: TDataTransferObject): String;
overload;
function getDeleteSQLString(Const pTOList: TDataTransferObjectList): TStringList;
overload;
constructor Create;
destructor Destroy;
override;
end;

来完成对SQL语句的解释.
返回数据对象列表和数据集的方法:
billList := DPWapper.SelectVOList(bill);
billDS := DPWapper.SelectVOList(bill);

客户端调用的方法:
业务对象.方法. 该方法再调用前面的二句.如果是简单的数据获取,可以不用业务对象再次包装,直接调用前面二句就行了.
 
事务处理,封装到TDataPerWapper 中.
function begin
Trans: Boolean;
function CommitTrans: Boolean;
function RollBackTrans: Boolean;
 
建议在中间层提交事务
 
后退
顶部