作者 内容
 xmlone  关于事务处理的问题

我最近在研究事务处理的问题,有很多不明的地方,请各位高手不吝赐教!
1。假设如下情况:
一个完整的事务可能包括a,b,c,d四个小事务,根据a的结果决定是否要执行b,c,d。
如果a的结果满足一定的条件则不用执行b,c,d那么一个完整的事务包括a就行了,否则一个完整的事务要包括a,b,c,d。

2。在事务执行的过程中,需要与用户交互,如等待用户确认后在执行下去,那如何保证事务的完整性呢?
 02/02/25 10:22 酷帖!    臭帖!    回复  
酷帖评价:           臭帖评价:
返回页首
 joy_wind  我的想法

我的想法,见笑了。
如果一个事务有多个分支,那么每个分支都是一个单独的事务;对一个单独的事务如何保证其完整性好像不用开发人员作太多的工作吧。 -:)
 02/02/25 10:36 酷帖!    臭帖!    回复  
酷帖评价:           臭帖评价:
返回页首
 mylshq  回复: 关于事务处理的问题

建议:
在一个事务的过程中最好不要与用户交互。
如果是我,这样处理:
将A事务最终的执行放到交互之后,将交互的问题作为一个中间结果保存,并不真正修改数据库,其后就可以按一个完整事务来处理。
 02/02/25 12:03 酷帖!    臭帖!    回复  
酷帖评价:           臭帖评价:
返回页首
 gsycl  如果事务嵌套不可避免...

在实际应用中,事务嵌套有时不可避免,尤其是OOD,一个事务可能需要多个对象联合动作。如果为保证事务的完整性,就必须将对象内部封装的内容公开,破坏对象封装完整性,反之亦然
 02/02/25 12:39 酷帖!    臭帖!    回复  
酷帖评价:           臭帖评价:
返回页首
 iami   回复: 关于事务处理的问题

第一个问题不是问题:
执行a
if 不需要bcd then
commit
return
else
执行 bcd
commit
end if
第二个问题:
绝对不允许在事务处理过程中和操作员进行交互,如果操作员不应答怎么办?单机系统这样做还勉强可以,但有多个客户端的情况下很容易造成死锁。
尽量让人工的选择在事务处理前全部作完,如果不行就将这个事务分割成两个事务,一个在选择前做完,另一个选择后再做。
如果由于操作员的选择,前一个事务必须回滚,那么只有辛苦你自己,编程来解决了。 事务并不是万能的:-)
 02/02/25 13:59 酷帖!    臭帖!    回复  
酷帖评价:           臭帖评价:
返回页首
 w_rose   事务处理的内部设计流程

数据库系统程序员需要比一般应用软件程序员懂得更多。一般程序员对事务处理的理解不够全面。事务处理的关键是在提交事务或者取消事务时,万一系统崩溃了,数据库在再次启动时,仍然需要保持数据可逻辑一致性。

最简单的事务处理过程如下:

1. 开始一个事务。进入“事务待命”状态。
2. 在“事务待命”状态,记录事务中改变的数据库记录。此改变不能直接改变数据库中的值,必须先用一个顺序的“事务日志”记录在一边。同时,对于要改变的原始记录加锁,让其它用户无法读和写。(考虑银行取款问题,可以发现如果此时两个用户都在对同一帐号取数,然后减去一定金额,在先后写回数据库,银行就亏钱了)。如果记录已经被其它事务加锁,则报错;同一事务中却可以重复加锁。
3. 在“事务待命”,如果用户给出commit transaction命令,则进入“事务拷贝”状态,拷贝所有加锁的记录成备份。
4. 上面3执行完,则进入“事务更新”状态,用“事务日志”中记录一一更新实际的数据库记录。
5. 上面4执行完,则进入“事务结束”状态,释放所有的记录锁,然后抛弃“事务日志”和备份的原数据库记录。
6. 上面5做完后,事务被删除。

但是,最为关键的是,事务系统必须执行以下过程:一但数据库由于软件、硬件问题发生故障,重启动后,一旦有事务没正常删除,则:

7. 如果在“事务待命”、“事务结束”状态,则重新从5中结束事务的动作开始执行。
8. 如果在“事务更新”状态,则重新从4开始更新记录,并继续想下执行。结果,虽然系统崩溃过,但事务仍然能正常提交。

Informix、Oracle、DB2等数据库的实际事务处理流程更复杂,目的是具有更好的抵抗系统错误性质,因为事务保护是业务系统安全稳定的最后一道防线(比用2个CPU、热备份等更重要。因为那些方法对已经混乱错误的数据照样保护,结果经常造成更多问题)。由于事务处理的流程比一般程序想像得复杂,因此可能会感到用起来比较繁琐。但是了解事务在保护数据库方面的良苦用心,就可以更好地设计出更灵活的业务流程。

你在问题1中谈“一个完整的事务可能包括a,b,c,d四个小事务”比较奇怪。既然是个过程构成一个事务,没必要中间在划分为4个小事务,问为中间任何操作出错都需要整个“回滚”到a之前。在执行完a后用一个if语句判断要不要再执行“b,c,d”就行,end if之后提交事务。

应用中包含的事务应当尽量让它“瞬间”完成,避免在比较忙时造成用户进程的互锁。事务比较频繁的系统,一秒钟有几个用户互锁就可能造成严重问题,因为事务是以一个稳定的频率来的,而服务器上互锁的进程越积越多,几个小时后,可能有上百台机器都死掉了,只能一台一台地重新开机,花费很多时间、金钱,还会被用户骂死!

但是并不是说事务之间就不能有用户交互。可以在用户3分钟还没确认后,就自动报告错误,并且取消事务。不过我从不冒这个险,而是使用下面方法。

将事务拆分成两段,需要非常深入地研究用户业务流程,研究用户在发现业务数据不一致时是如何纠正的,并且继承用户手工操作流程。这样,软件分析的工作量相应加大了。有时,这是必然的,应当说服用户接受这种现象,并且与开发者一起逐步解决。

比如,卖彩票的交易,用户输入彩票号码,此时在POS机打印彩票并且记账。这并不需要在卖彩票时与后台服务器实时联网,只要每隔10分钟上传一次数据就行了。只有这样,才能在现有的硬件和网络条件下使得彩票销售开展起来。如果开发者固守者彩票号码录入、服务器记账、前台打印合并为一个事务的天真想法,其产品一定会在激烈的市场中败阵。

当然,随着硬件、软件、网络的不断变化,如何灵活应用事务的方法会不断变化,没有一定的规矩,关键要看软件的效果。虽然大的事务可能不断拆分成小的事务,中间用业务流程联系起来;同时,合并一些小的事务或者由计算机自动处理业务数据不一致问题,从而给用户提供网络上的“傻瓜相机”一样的易用、稳定的产品仍然是今天最有挑战意义的软件工程目标。
 02/02/25 17:26 酷帖!    臭帖!    回复  
酷帖评价:           臭帖评价:
返回页首
 q_t   回复: 我的想法

事务的拆分应该根据具体的工作情况定夺 ,否则按你的想法(可能是我想的极端)盖楼我们知道要砖头和水泥、木材等、但是为了使大楼更加牢固,你于是就去研究沙土,然后在工地旁盖个砖厂,需要什么样子的转就做什么样子的砖,结果是一定满足你的要求,但花费的工时难以计算。
这也就是做事情有个度的问题,如果这个东西可以复用,我们就把他们封装到一起(像砖头在该大楼的各个方面都能用上);如果这个东西不可复用,拆开后倒是很多部分可以复用的话,那就可以拆开(这要根据工作量定夺)。
 02/02/25 20:41 酷帖!    臭帖!    回复  
酷帖评价:           臭帖评价:
返回页首