日前台湾高铁及其系统包商所开发的订票系统
曾出现大量重复订位之情形
产生了「车次
时段与路程」都一模一样的重复序号
类似此种订票系统
除了可使用 Web
based 架构外
若考虑到断线的处理作业
是否能在断线的情况下还能够交易
那么还可考虑 client
server 的架构
如此一来就要设计各个 client side 可以配给的车号
数量
以及恢复断线后再同步的机制
才能够实时处理
并尽可能避免重复划位的现象
若要避免产生重复划位先剔除系统架构的分析设计OOAD 落实与否的问题不看单就编程技术来探讨较简单的做法是采用 ADONET 的「交易 (Transaction)」写法让某位订票者在交易座位 A 时其它人都无法读取此 A 座位一直到他的交易结束为止亦可搭配使用 dirty read 去强行读取类似数据库的「独占锁定 (exclusive lock)」让某人修改数据时其它人连读取都不行 (亦会限制同时在线数量)此种「独占锁定」类似 ADONET 的「封闭式 (悲观) 并行存取」机制虽然会长时间从数据被读取开始即将其锁定但至少可保证交易一定有效像这种资料 lock 的机制只要撰写 Transaction 程序或是调整数据库的锁定策略锁定提示就可做到此外还可搭配使用数据库的 TimeStamp 计数器判断「数据列 (row)」中的任何值是否有任何改变另外 SQL Server 还有更优越的「Snapshot Isolation 快照隔离模式」其提供一种新的隔离层级可将写入流程读取流程作适当地隔离使得读取动作不等待写入动作写入动作不干扰读取动作以提高数据的可用性加快交易的执行速度
至于 ASPNET / Visual Studio 亦提供了入门级的解决方案可由 SqlDataSource 等数据存取控件的图形设定接口中勾选「进阶」按钮内的「使用开放式并行存取」选项即可启动沖突侦测机制 (ConflictDetection 属性)此举会将控件预设的「OverwriteChanges」改为「CompareAllValues」并判断数据从刚才第一次读取到更新的这段期间内是否曾被其它使用者变更过此一选项亦即 ADONET 的「开放式 (乐观) 并行存取」机制只有当数据正在修改时才会进行锁定并在修改完后再对各个「数据域 (column)」的新旧数据进行比对看是否曾在这段期间内抢先被其它使用者修改了同一笔记录但其它所有使用者仍可在此时去读取类似于数据库的「共享锁定 (shared lock)」若未勾选「使用开放式并行存取」此一选项时即会采用预设的「后进先写入」机制这种做法也是只在修改时才会锁定但不会将更新后的数据与原始数据作比对因此有可能发生欲修改的数据被其它使用者覆写掉之情形