在大多数环境中,事务处理的根本是业务过程而不是数据访问逻辑组件或业务实体组件。这是因为业务过程一般要求事务处理跨多个业务实体而不仅仅是单个业务实体。
然而,也可能出现在没有高层次业务过程的帮助下对单个业务实体执行事务性操作的情况。例如,要把一个新客户添加到前面讨论的数据库中,您必须执行以下操作:
- 在 Customer 表中插入新的一行。
- 在 Address 表中插入新的一行或多行。
只有这两个操作都成功后客户才会被添加到数据库中。如果 Customer 业务实体不会成为启动该事务处理的更大的业务过程的一部分,则应在 Customer 业务实体中使用手动事务处理。手动事务处理不要求与 Microsoft 分布式事务处理协调器 (DTC) 之间进行任何进程间通信,因此比自动事务处理要快得多。
图 11 所示为确定使用手动事务处理还是自动事务处理的方法。由于 COM+ 事务处理的系统开销,建议将事务处理放到数据库中并在存储过程中控制事务性行为(如果可能)。
图 11:确定如何实现事务处理
注意:如果从基于 ASP.NET 的客户端进行调用,并且没有用于启动事务处理的业务过程,则您可能会从 ASP.NET 代码中启动该事务处理。这种设计并不好;您决不能从基于 ASP.NET 的客户端启动事务处理,而应将数据的展示与业务过程相分离。此外,由于网络滞后等问题还会导致性能问题,因为这是要实际部署在其他层上的最常见的层。在数据访问逻辑组件中使用手动事务处理的建议
在数据访问逻辑组件中实现手动事务处理时,请考虑以下建议:
- 尽可能在存储过程中执行处理。使用 Transact-SQL 语句 BEGIN TRANSACTION、END TRANSACTION 和 ROLLBACK TRANSACTION 控制事务处理。
- 如果没有使用存储过程,并且也不会从业务过程中调用数据访问逻辑组件,则可以使用 ADO.NET 来编程控制事务处理。
虽然 COM+ 事务处理会带来一些系统开销,但自动事务处理能够提供比手动事务处理更简单的编程模式,而且在事务处理跨多个分布式数据源(与 DTC 一起工作)时必须使用自动事务处理。在数据访问逻辑组件中实现自动事务处理时,请考虑以下建议:
- 数据访问逻辑组件必须是从 System.EnterpriseServices 命名空间中的 ServicedComponent 类继承而来。注意,使用 COM+ 服务注册的所有程序集都必须具有严格的名称。
- 使用 Transaction(TransactionOption.Supported) 属性注释数据访问逻辑组件,以便可以在同一组件中执行读写操作。与 Transaction(TransactionOption.Required) 不同,此选项在不需要事务处理时避免了不必要的系统开销,而前者始终会要求事务处理。
以下代码示例显示了如何在数据访问逻辑组件类中支持自动事务处理:
using System.EnterpriseServices;
[Transaction(TransactionOption.Supported)] |
如果使用自动事务处理,则数据访问逻辑组件应在事务处理中表明操作是否成功。如果要隐式表明,应使用 AutoComplete 属性注释您的方法并在操作失败时发出一个异常。如果要显式表明,应对 ContextUtil 类调用 SetComplete 或 SetAbort 方法。
在业务实体组件中使用自动事务处理在实现带有行为的自定义业务实体组件时,可以使用自动事务处理来指定这些对象的事务性行为。有关使用自动事务处理指定业务实体组件事务性行为的建议与前述有关在数据访问逻辑组件中实现自动事务处理的建议相同。
注意:如果业务实体组件不包含任何要求其在事务处理中表明是否成功的业务逻辑,则它可以忽略事务处理环境。自定义业务实体组件不需要从 ServicedComponent 继承;事务处理环境仍将继续其流程,但实体组件将忽略事务处理环境。验证
您可以在应用程序的许多层上进行数据验证。各层适用不同的验证类型:
- 在提交数据之前,客户端应用程序可以在本地验证业务实体数据。
- 使用 XSD 架构接收业务文档时,业务过程可以验证这些文档。
- 数据访问逻辑组件和存储过程可以验证数据,以确保引用的完整性并强制遵循约束以及重要的业务规则。
常用验证有两种:
- 即时点验证。这是在一个特定时点执行的验证。例如,在接收 XML 文档时由业务过程对其进行验证。
- 连续验证。这是在应用程序的许多不同层次上持续进行的一种验证。连续验证的示例包括:
- 用户界面可以指定字段的最大长度以防止用户输入过长的字符串。
- DataSet 可以指定数据列的最大长度。
- 自定义业务实体组件可以对实体数据执行范围检查、长度检查、非空检查以及其他简单测试。
- 数据访问逻辑组件、存储过程和数据库本身可以执行类似的测试,以便在将数据保存到数据库之前确保其有效性。
有时,您可能希望实现额外的聚合过程或转换过程。这种方法在验证和转换经常变化时可能很有用,但会损失性能。例如,如果一个 ISV 想要使用相同的组件支持数据库架构的两个版本,则您可以创建一个单独的组件来执行两个数据库架构版本之间的验证和转换。
如何使用 XSD 架构验证 XML要使用 XSD 架构验证 XML 文档,请执行以下步骤:
- 创建一个 XmlValidatingReader 对象作为 XmlTextReader 对象的包装,如以下代码所示:
' 创建 XmlValidatingReader 对象,以读取和验证 Product.xml
XmlTextReader tr = new XmlTextReader("Product.xml");
XmlValidatingReader vr = new XmlValidatingReader(tr);
- 通过使用 ValidationType 枚举指定所需的验证类型。.NET Framework 支持三种类型的 XML 验证:
- 文档类型定义 (DTD);指定 ValidationType.DTD
- Microsoft XML 精简数据 (XDR) 架构;指定 ValidationType.XDR
- W3C 标准 XSD 架构;指定 ValidationType.Schema
以下代码显示了 ValidationType 枚举的使用:
vr.ValidationType = ValidationType.Schema; ' 指定 XSD 架构验证
- 注册一个验证事件处理程序方法,如以下代码所示:
vr.ValidationEventHandler += new ValidationEventHandler(MyHandlerMethod);
- 提供一个验证事件处理程序方法的实现,如以下代码所示:
public void MyHandlerMethod(object sender, ValidationEventArgs e)
{
Console.WriteLine("验证错误:" + e.Message);
}
- 读取和验证文档,如以下代码所示。验证错误将被验证事件处理程序方法拾取。
try
{
while (vr.Read())
{
// 适当处理 XML 数据...
}
}
catch (XmlException ex)
{
Console.WriteLine("XmlException: " + ex.Message);
}
vr.Close();
以下代码片段显示了如何在自定义实体的属性存取器中进行简单验证。如果验证测试失败,您可以发出一个异常以显示问题的性质。也可以在属性存取器集合中使用正则表达式来验证特定的数据和格式。
public class ProductDALC { ... public short ReorderLevel { get { return reorderLevel; } } set { if (value < 0) { throw new ArgumentOutOfRangeException("ReorderLevel 不能为负数。"); } reorderLevel = value; } // 加上 ProductDALC 类中的其他成员... |