通常,我们在数据库层处理这一点,因为单独计算机上的各个应用程序彼此并不直接了解。应用程序可以在执行操作之前或定期检查数据库本身,或者底层存储过程可以使用某种简单的表和信号量锁定来管理模式。
在单台服务器上的非分布式Web应用程序上,您可以使用应用程序对象相当容易地处理这一问题,因为实际上只有一个应用程序,而且它可以相当容易地监视用户活动。
假设您只有两种模式,并且所有内容都在存储过程中处理:
一个用户进行某种过账操作和正常模式的模式。假设过账操作中的操作相对简单,为了清楚起见,我们将省略确保没有竞争条件的代码,并将所有代码内联,而不是封装到其他SP或函数中:
CREATE PROCEDURE Post
AS
BEGIN
UPDATE ModeControl
SET Mode = 'POSTING'
UPDATE Payments
SET Whatever = whatever
WHERE whatever
UPDATE ModeControl
SET Mode = 'NORMAL'
END
CREATE PROCEDURE IsPosting -- poll this in your app or before performing operations
AS
BEGIN
IF EXISTS (SELECT * FROM ModeControl WHERE Model = 'POSTING')
RETURN 1
ELSE
RETURN 0
END
CREATE PROCEDURE Normal1
AS
BEGIN
-- Catches potential problems at database even though app shouldn't call in 'POSTING' more
IF EXISTS (SELECT * FROM ModeControl WHERE Model = 'POSTING')
RAISERROR...
-- Perform Normal1 operations
END
CREATE PROCEDURE Normal2
AS
BEGIN
IF EXISTS (SELECT * FROM ModeControl WHERE Model = 'POSTING')
RAISERROR...
-- Perform Normal2 operations
END
显然,如果您有一个完整的数据访问层和一些框架位,那么您可以修饰您的方法,并使用反射来自动分类您的方法,并用关于不允许的模式的检查将它们包装起来,以将其绑定到某种状态机类型的东西中。