日期:2014-05-20  浏览次数:20748 次

面向对象编程如何解决事务处理问题
使用面向对象编程,有些业务是需要以事务方式进行处理的
比如销售出库,需要对数据库进行:
1.保存出库单
2.生成财务凭证
3.冲减库存
简单伪码:
  出库单的保存方法
Save()
{
  保存出库单;
  生成财务凭证类实例,调用财务凭证类的保存方法保存财务凭证
  生成物资类实例,调用物质类实例冲减库存方法冲减库存
}
业务层原则上不直接操作数据库,是通过调用类提供的方法来实现,但需要保证操作的原子性,请教大家有没有好的方法,在不破坏面向对象设计原则的基础上保证事务操作的原子性

------解决方案--------------------
将后台业务逻辑写到SP, 不能处理的在代码内用Transaction.

如果数据量大请做好思路准备,因为很容易“搞死”服务器。

我用Delphi写过一段生成“批卡”的功能,大概300条记录涉及4张表吧,经常跑死服务器,死锁啊!
保存的时候超慢,后来优化了代码,将某部分业务脱离事务,问题解决速度且快了2倍。

事务只适合处理少量数据,是不是SQL天生这么弱?


------解决方案--------------------
另外:批卡表的记录在300W以上。所以慢。。。
------解决方案--------------------
1. AOP框架, 实现事务的切入。 比如postsharp、unity、spring.net等等。推荐这种。
2. 使用MSDTC,分布式服务。 适用于分布式事务(跨数据库),性能稍差,不如dbtransaction稳定。
3. 传递dbTransaction对象, 这样代码可读性较差。
------解决方案--------------------
在不破坏面向对象设计原则的基础上保证事务操作的原子性
-------------------------------------
这确实是个难题。。。但如果你的系统到处都是这样的矛盾,冲突很大的话,会不会是设计过度了?
象你说的保存出库单的方法里,那些1.2.3一步步的操作,把它们单独提出来有意义吗??
------解决方案--------------------

通过合理的设计避免多步操作
1.事实上,客户并不希望由于财务凭证过账失败,导致出库单回滚;
过账失败的单据应该由代理程序自动重试,
重试失败的,放进代办事宜,由人工干预,
其实这时候,往往是已经有异常情况发生了,静默回滚是不合适的;
2.根据原始资料计算库存,放一个库存字段本身就已经违反会计原则了