我们生活的这个世界,是什么样的世界呢?世界是物理的世界,因为他是由物质的组成的。但是从另一个角度来说,世界是信息的世界。为什么呢,因为这个世界无实无刻不被各种各样的信息所包围着。 包括我们自己,都是信息决定的。为什么?是什么决定了我们是人,而不猪或者是牛马之类的——是DNA。DNA是什么,DNA是一个又一个的碱基对,他们就像是一串又一串的0和1。他们的不同的排列组合,决定了我们是人,而另一些“人”是猪或者牛马。DNA本质上,是一种信息的载体,这些信息,是一段又一段的生物程序。各类细胞,依据这些程序进行运行。程序最终运行的结果,就是生成了我们——人,他们——猪或牛马。从这个意义上来说,DNA是原始信息,而我们是衍生的信息。 信息,是需要载体的,这个载体,也许是DNA,也许是光,也可以是其它的东西。我们人类的视觉信息,就是从光中获取的。而计算机运算过程中的信息,由一个又一个的伏特来承载。硬盘中的信息,由一个又一个高斯来承载。我们听到的声音,由一个又一个的振波所承载。不知是谁说的,也许是爱因斯坦,我记不清了——物质是能量的凝聚态。而我们的信息,本质上都是由能量所承载的。能量的传播的速度不是无限的,是有限的,最高的是光速。这就决定了信息的传播速度也就有了上限。这一点,在天体物理学上体现的最明显——经常会有,几百年前的超新星爆炸,我们到现在才观察到。 这一切都说明了什么?说明了信息是滞后的,信息从它的源头出发。到我们接受到它,是有一个过程的,是要经历时间的。这个时间过程中,信息的源头也许已经不是信息发出时的哪个样子了。信息发出的地方是信息的源,而我们接受到的信息,是信息的像。信息滞后说明了什么?说明了像不等于源。当我们通过像获取源所要表达的信息时,这个信息也许已经过时了。 说了这么多,好像与软件开发与程序设计毫无关系。如果有人这么认为,这就错了。信息的滞后性,是实际应用软件设计,尤其是基于Web的应用软件设计时必须认真对待的一个问题。 假设有这么一个业务,当前的状态是A。此时I、II两人都可以进行业务操作。I单独操作会使状态变成B。而II单独操作会使状态变成C。I先操作,II后操作的结果会使状态变成D。II先操作,I后操作的结果会使状态变成E。I、II两个人同时从系统中获取了业务的信息,此时,两人都获取到当前任务处理A状态。I先操作了,提交后业务状态变成了B。而后,II在I操作过后一段时间才去操作(为什么?也许他去上了个厕所,天才知道!),此时,业务的状态变成了C。 ??不对!应该是状态D。人们也许会这么说。但实际情况,的确会像上面那样。因为双方者是以状态A为基础,单独操作的结果。这个问题是否有点似曾相识?是的,它就是多线程中的多个线程同时对一个变量++的问题的现实世界版。但是,这里不能对变量(也就是业务)加锁,因为一个业务的操作过程,也许要几分钟,也许要几个小时(当中可以去上厕所 :-) ),这样加锁是不现实的。再者,操作过程中,如果你在获取业务条件是加了个锁。而之后,你又放弃了操作。这时,锁怎么办?后面的人会因为你的关系而无法进行操作。 怎么解决这个问题,可能参考分布式算法中的乐观并发控制。它的实质就是要求在业务提交时,对业务基于的前提条件进行检查,判断。如果业务操作、计算所基于的前提条件,在业务提交时更动过,那么,就应撤消(实际应该称为阻止)这个业务操作。如果前提条件没有更动过,对业务的操作结果进行正常的提交。 这里要引出的是一个常用的基于WEB+数据库应用软件设计中需要遵守的一个原则。如果遵守这个原则,应用软件不会出现上面的错误。反之,你就祈祷吧! 这条原则就是: 应用软件在提交业务操作时,必须对业务操作所基于的原始条件进行检查。如果原始条件变动,则应阻止业务操作的进行。 严家俊 2011年2月20日 凌晨 于家中