C# 外部数据库记录修改的应用程序自我感知
如何让应用程序知道数据库记录是由外部应用程序而不是应用程序本身更改或创建的C# 外部数据库记录修改的应用程序自我感知,c#,sql,sql-server,C#,Sql,Sql Server,如何让应用程序知道数据库记录是由外部应用程序而不是应用程序本身更改或创建的 是否向数据库记录添加特殊校验和,或者如何停止对数据库的外部更改?(如果被黑客攻击,黑客决定添加新记录或更改现有数据库记录)通过ORM 某些/所有ORM将生成SQL以匹配对象的每个值,并在所有这些条件匹配的地方运行更新。在这种情况下,重要的是某些字段必须作为“变更指示器”保持一致 --Customer-- ID int FirstName varchar(10) LastName varchar(10) C
是否向数据库记录添加特殊校验和,或者如何停止对数据库的外部更改?(如果被黑客攻击,黑客决定添加新记录或更改现有数据库记录)通过ORM 某些/所有ORM将生成SQL以匹配对象的每个值,并在所有这些条件匹配的地方运行更新。在这种情况下,重要的是某些字段必须作为“变更指示器”保持一致
--Customer--
ID int
FirstName varchar(10)
LastName varchar(10)
ChangedOn datetime
UPDATE Customer
SET FirstName = 'SomeChange'
WHERE FirstName = 'Oldvalue'
andLastName = 'OldValue'
and ChangedOn = SomeDate
自制的
除了ORM之外,考虑为您的表实现一个更新存储的PROC,它将包括每当更新一个记录时用一个新的时间戳更新到CeaDeon字段的更新。这将允许您自己管理更新。在类中定义此时间戳的属性,并在从其数据存储读取时将其填充到对象中。当保存回数据存储时,根据时间戳的值与数据库中当前存储的内容进行检查。您可以创建一个LastUpdated字段,该字段可以使用触发器进行更新 然后,应用程序可以利用该文件检查数据是否过期 这是一个小例子
CREATE TABLE Vals(
ID INT,
Val VARCHAR(10),
DateCreated DATETIME DEFAULT GetDate(),
DateUpdated DATETIME DEFAULT GetDate()
)
GO
CREATE TRIGGER Upd ON Vals
AFTER UPDATE
AS
UPDATE Vals
SET DateUpdated = GetDate()
FROM Vals INNER JOIN
inserted ON Vals.ID = inserted.ID
Go
INSERT INTO Vals (ID, Val) SELECT 1, 'A'
SELECT *
FROM Vals
GO
UPDATE Vals SET Val = 'B'
SELECT *
FROM Vals
GO
DROP TABLE Vals
GO
大多数应用程序使用
最新的写赢策略。虽然这对架构师没有吸引力,但它很容易编码,而且几乎总是足够好
如果有1%的应用程序确实需要并发性:
- 添加
UpdateDt
和UpdatedBy
列。如果自读取记录后,UpdateDt
已更改,请发出警告
- 存储所读取行的值,并使用副本存储任何修改。在写入数据库之前,请检查原始值是否仍然匹配。如果他们没有,就发出警告。(这是.NET
数据集使用的策略)
- 添加一个锁定表。当用户打开记录时,为其设置锁。当其他用户试图打开行进行修改时,发出错误消息。与其他方法不同,这称为
悲观锁定,因为它甚至在潜在冲突发生之前就发出警告
这可以在SQL Server中完成,而无需在代码中使用触发器、存储过程或强制时间戳-请参阅列类型。正常的“enterprisey”方法是使用消息队列,通过使用触发器发布的消息队列,每当有人写入特定表时,应用程序都可以获取消息。它还有一个很大的优势,即你的应用程序不需要运行,但可以在开始时读取队列,如果你愿意,也可以按计划读取队列
请参见有三个问题需要回答: 如何确定行已更改 你有很多选择:
rowversion
列(在较旧版本的SQL Server中称为timestamp
),该列将在每次更改行时自动更新。这只会告诉您某些内容已更改,而不会告诉您更改了哪个列或是谁更改了它显而易见的选择是限制对数据库的访问。仅允许应用程序帐户访问数据库和/或表和存储过程。此外,您需要锁定管理员和开发人员对数据库的访问,以便只有少数人可以访问数据库。与良好的日志记录相结合,可以防止出现神秘行。当任何应用程序/用户都可以访问表(或表上的可更新视图)时,触发器是捕获所有更改并采取适当操作的唯一可靠方法 因为触发器不是一个很好的应用程序设计工具,无法实现业务规则或一般的数据库完整性,所以在大多数以数据库为中心的应用程序中,数据库确实有自己的职责,有自己的周界和服务定义,您可以分层处理—没有人可以访问表,您有不可更新的视图,大多数访问权限都需要通过存储过程 即使在数据库具有开放边界的应用程序中,业务规则也在应用程序的数据层中强制执行,所有访问都应通过该层。不幸的是,在这些情况下,开放式外围数据库实际上无法保证数据的高阶完整性或期望值,除非帐户被真正锁定,并且只有通过代码中的数据访问层才能确保访问
如果您必须让人们直接更新表,并且您需要在这些例外情况下强制执行相同的规则,那么触发器实际上是您唯一的选择。至少您可以使用相对简单的审核触发器来审核所有更改。检测客户端脱机时发生的更改 这是和的工作。这两种技术都源自复制(一种来自合并,一种来自Tra)