背景:
一个用户系统里的充值功能,假设WINFORM程序,当用户输入一定的充值金额并提交后,系统需要完成两个操作:
1是更新此用户的级别。
2是将此次充值操作记录到数据表中以备查询。
![]()
由于项目需要,更新用户信息和记录充值信息分别做成两个类库项目,各自完成更新用户表和插入充值历史表的功能,便于扩展和维护。
![]()
需求:
当用户提交充值的时候,要求先记录此次充值信息,然后更新用户表的GRADE字段。如在此过程中意外中止(如断电,服务器当机等),则回滚事务,取消此次的充值操作。
分析:
首先,更新用户等级和保存充值信息这两个操作已经分别在BLL_User和BLL_Pay两个类库中完成,所以,通常的T-SQL和ADO。NET级别的事务,已满足不了跨组件(或跨项目)的数据提交
![]()
![]()
![]()
以上是普遍的实现方式,BLL_User和BLL_Pay分别完成用户等级的更新和充值信息的记录,两者分别执行,并没有数据事务的支持。
首先在解决方案中增加一个用于存储临时待处理语句的项目,暂定只有一个类,并且类中只有一个公有静态变量。
![]()
修改USER和PAY两个类如下:
![]()
![]()
然后修改主窗体按钮事件代码
![]()
这样通过一个事务ID将待处理的SQL语句暂存到一个公有的静态字典中,每个组件(或者是类库)在执行各自的操作时,根据当前对象的事务ID是否有值来判定是否需要暂存语句而不执行。以上代码仅测试用,当中还有很多问题,比如对异常的捕获、提交事务后没有清除字典中的当前事务、当程序意外当掉时虽不会提交但也无法保存(可实时存XML方式解决),实际开发过程中情况可能各不相同,大概思路是这样。
注:
补充一下,实际开发当中某个组件进行的操作未必是针对数据库,还可能比如写磁盘文件,发EMAIL,针对这类组件的事务支持,可以将字典中的VALUE类型改为一个代理方法,这样当提交事务的时候一次性执行所有组件当中记录的操作,而不是仅仅写数据库。
一个用户系统里的充值功能,假设WINFORM程序,当用户输入一定的充值金额并提交后,系统需要完成两个操作:
1是更新此用户的级别。
2是将此次充值操作记录到数据表中以备查询。

由于项目需要,更新用户信息和记录充值信息分别做成两个类库项目,各自完成更新用户表和插入充值历史表的功能,便于扩展和维护。

需求:
当用户提交充值的时候,要求先记录此次充值信息,然后更新用户表的GRADE字段。如在此过程中意外中止(如断电,服务器当机等),则回滚事务,取消此次的充值操作。
分析:
首先,更新用户等级和保存充值信息这两个操作已经分别在BLL_User和BLL_Pay两个类库中完成,所以,通常的T-SQL和ADO。NET级别的事务,已满足不了跨组件(或跨项目)的数据提交



以上是普遍的实现方式,BLL_User和BLL_Pay分别完成用户等级的更新和充值信息的记录,两者分别执行,并没有数据事务的支持。
首先在解决方案中增加一个用于存储临时待处理语句的项目,暂定只有一个类,并且类中只有一个公有静态变量。

修改USER和PAY两个类如下:


然后修改主窗体按钮事件代码

这样通过一个事务ID将待处理的SQL语句暂存到一个公有的静态字典中,每个组件(或者是类库)在执行各自的操作时,根据当前对象的事务ID是否有值来判定是否需要暂存语句而不执行。以上代码仅测试用,当中还有很多问题,比如对异常的捕获、提交事务后没有清除字典中的当前事务、当程序意外当掉时虽不会提交但也无法保存(可实时存XML方式解决),实际开发过程中情况可能各不相同,大概思路是这样。
注:
补充一下,实际开发当中某个组件进行的操作未必是针对数据库,还可能比如写磁盘文件,发EMAIL,针对这类组件的事务支持,可以将字典中的VALUE类型改为一个代理方法,这样当提交事务的时候一次性执行所有组件当中记录的操作,而不是仅仅写数据库。
浙公网安备 33010602011771号