WizardWu 編程網

一位台灣的工程師,接觸 .NET 逾十年,近年研究 SQL Server、Performance Tuning、手機應用

博客园 首页 新随笔 联系 订阅 管理

日前台湾高铁及其系统包商所开发的订票系统,曾出现大量重复订位之情形,产生了车次、时段与路程都一模一样的重复序号。类似此种订票系统除了可使用 Web-based 架构外,若考虑到断线的处理作业,是否能在断线的情况下还能够交易,那么还可考虑 client-server 的架构,如此一来就要设计各个 client side 可以配给的车号、数量,以及恢复断线后再同步的机制,才能够实时处理,并尽可能避免重复划位的现象。

若要避免产生重复划位,先剔除系统架构的分析设计OOAD 落实与否的问题不看单就编程技术来探讨,较简单的做法是采用 ADO.NET 的「交易 (Transaction)写法。让某位订票者在交易座位 1A 时,其它人都无法读取此 1A 座位,一直到他的交易结束为止,亦可搭配使用 dirty read 去强行读取;类似数据库的「独占锁定 (exclusive lock)」,让某人修改数据时其它人连读取都不行 (亦会限制同时在线数量)。此种「独占锁定」类似 ADO.NET 的「封闭式 (悲观) 并行存取」机制,虽然会长时间从数据被读取开始即将其锁定,但至少可保证交易一定有效。像这种资料 lock 的机制只要撰写 Transaction 程序,或是调整数据库的锁定策略、锁定提示就可做到。此外还可搭配使用数据库的 TimeStamp 计数器,判断数据列 (row)」中的任何值是否有任何改变。另外 SQL Server 2005 还有更优越的Snapshot Isolation 快照隔离模式,其提供一种新的隔离层级,可将写入流程、读取流程作适当地隔离,使得读取动作不等待写入动作、写入动作不干扰读取动作,以提高数据的可用性、加快交易的执行速度。

至于 ASP.NET 2.0 / Visual Studio 2005 亦提供了入门级的解决方案,可由 SqlDataSource 等数据存取控件的图形设定接口中,勾选「进阶」按钮内的「使用开放式并行存取」选项,即可启动冲突侦测机制 (ConflictDetection 属性)。此举会将控件预设的「OverwriteChanges」改为「CompareAllValues」,并判断数据从刚才第一次读取到更新的这段期间内,是否曾被其它使用者变更过,此一选项亦即 ADO.NET 的「开放式 (乐观) 并行存取」机制,只有当数据正在修改时才会进行锁定,并在修改完后再对各个「数据域 (column)」的新旧数据进行比对,看是否曾在这段期间内抢先被其它使用者修改了同一笔记录;但其它所有使用者仍可在此时去读取,类似于数据库的「共享锁定 (shared lock)」。若未勾选「使用开放式并行存取」此一选项时,即会采用预设的「后进先写入」机制,这种做法也是只在修改时才会锁定,但不会将更新后的数据与原始数据作比对,因此有可能发生欲修改的数据被其它使用者覆写掉之情形。


-------------------------------------------------
(本文在版工的旧 Blog 中,发表日期为 2007/01/07)
(本文有些 Hyperlink 是连到台湾的网站,内地的网友可能会无法开启连结)

posted on 2008-07-04 00:00  WizardWu  阅读(864)  评论(0编辑  收藏  举报