您的位置:软件 > 开发者网络 > 微软开发专栏 > 技术专题 > 正文
DataSet的数据并发异常处理
[文章信息]
作者:陶刚编译
时间:2004-02-25
出处:yesky
责任编辑:方舟
[文章导读]
ADO.NET为提高数据密集型(data-intensive)应用程序的性能、简化这类程序的建立过程提供了多种技术
advertisement
热点推荐
· 11.10软件精选 FW实用设计
· IE最新安全漏洞补救几大措施
· M牛的网络生活之下载篇
· Norton Ghost 9.0全新体验
· InstallShield简明使用教程之前言
[正文]

上一页  1 2 3 4 5  下一页

  示例程序

  一个虚拟的公司使用该顾客服务应用程序建立顾客订单,更新顾客的个人信息。有很多客户销售代表(CSR)在桌面上使用该应用程序。CSR使用电话获取订单,从顾客那儿收集个人信息和支付信息。顾客记录保存在数据库中以提高回头客处理订单的速度,CSR接着建立一个订单并把产品项添加上去,指定数量和目前的价格,所有的信息收集后,CSR点击Place Order按钮,向数据库中插入顾客和订单记录。

  CSR也使用应用程序执行通过电子或者缓慢的邮件发送给公司的请求。这些请求在CSR间均匀分开,在每天早晨发送给他们,CSR通过电话执行那些请求。系统设计要提高请求的实现速度,所有的顾客在CSR之间共享。顾客的每个请求,无论通过电话或者邮件,都被不同的CSR处理,增加了发生数据并发性问题的机会。
为了提高性能,应用程序在内存中保持了一个用顾客和订单信息填充的数据集对象。因为很多雇员同时使用该应用程序,就会有许多活动数据的不连接的快照,它们都在雇员的工作站上。所有顾客的维护、订单输入和订单维护都使用名为dsAllData的数据集对象。图1是建立dsAllData的代码,它是全局模块的一部分,因此应用程序中的所有窗体都能使用它。

Const connString = "server=localhost;database=northwind;uid=sa;pwd="
Public connCustSvc As SqlClient.SqlConnection
Public daCustomer As SqlClient.SqlDataAdapter
Public cbCustomer As SqlClient.SqlCommandBuilder
Public daOrders As SqlClient.SqlDataAdapter
Public cbOrders As SqlClient.SqlCommandBuilder
Public daOrderDetail As SqlClient.SqlDataAdapter
Public cbOrderDetail As SqlClient.SqlCommandBuilder
Public dsAllData As DataSet
Public Sub Main()
 connCustSvc = New SqlClient.SqlConnection(connString)
 daCustomer = New SqlClient.SqlDataAdapter("SELECT * FROM Customer", connCustSvc)
 cbCustomer = New SqlClient.SqlCommandBuilder(daCustomer)
 daOrders = New SqlClient.SqlDataAdapter("SELECT * FROM Orders", connCustSvc)
 cbOrders = New SqlClient.SqlCommandBuilder(daOrders)
 daOrderDetail = New SqlClient.SqlDataAdapter("SELECT * FROM OrderDetail", connCustSvc)
 cbOrderDetail = New SqlClient.SqlCommandBuilder(daOrderDetail)
 dsAllData = New DataSet()
 daCustomer.MissingSchemaAction = MissingSchemaAction.AddWithKey
 daCustomer.Fill(dsAllData, "Customer")
 daOrders.MissingSchemaAction = MissingSchemaAction.AddWithKey
 daOrders.Fill(dsAllData, "Orders")
 dsAllData.Tables("Orders").Columns("Total").DefaultValue = 0
 daOrderDetail.MissingSchemaAction = MissingSchemaAction.AddWithKey
 daOrderDetail.Fill(dsAllData, "OrderDetail")
 Application.Run(New frmCustomerMaintenance())
End Sub

图1.填充数据集对象

  建立dsAllData的代码建立了一个空的数据集对象、三个数据适配器(DataAdapter)和三个命令构造器(CommandBuilder)。每个数据适配器在适当的表上执行一个简单的"SELECT *"操作,而命令构造器用需要的剩余信息填充数据集,使它有插入(insert)、更新(update)和删除(delete)的能力。主程序使用数据适配器对象和所有三个表中的数据填充dsAllData,接着使用Customer Maintenance窗体开始应用程序。
图2显示的是Customer Maintenance屏幕,它有一个绑定到dsAllData的Customers数据表的DataGrid对象。这个简单的表格允许CSR编辑顾客的任意基本属性。因为该表格绑定到了Customers数据表,表格中的任何改变都将自动存储到数据表中。dsAllData将保存这些值,直到CSR点击Save Changes按钮明确地告诉窗体更新下层数据源为止。


图2. Customer Maintenance表格允许编辑

  为了输入订单,使用图3中的代码建立了几个新行并添加到dsAllData中。首先建立一个Order记录,接着在数据表OrderDetail中为订单的每个项建立几个记录。当所有必须的行添加到dsAllData后,一个适当的数据适配器的Update方法调用将用新行更新下层数据源。

Private Sub CreateOrder()
 Dim dr As DataRow
 dr = dsAllData.Tables("Orders").NewRow
 With dr
  .Item("DateOrdered") = Now
  .Item("CustomerID") = 1
  .Item("ShipToAddress") = "123 Main"
  .Item("ShipToCity") = "Kansas City"
  .Item("ShipToState") = "MO"
  .Item("ShipToZip") = "12345"
 End With
 dsAllData.Tables("Orders").Rows.Add(dr)
 AddOrderDetail(dr.Item("ID"), 1, 1, 9.99)
 AddOrderDetail(dr.Item("ID"), 2, 2, 4.99)
 daOrders.Update(dsAllData.Tables("Orders"))
 daOrderDetail.Update(dsAllData.Tables("OrderDetail"))
End Sub

Private Sub AddOrderDetail(ByVal OrderID As Integer, _
ByVal ProductID As Integer, ByVal Quantity As Integer, _
ByVal Price As Single)

 Dim dr As DataRow
 dr = dsAllData.Tables("OrderDetail").NewRow
 With dr
  .Item("OrderID") = OrderID
  .Item("ProductID") = ProductID
  .Item("Quantity") = Quantity
  .Item("Price") = Price
 End With
 dsAllData.Tables("OrderDetail").Rows.Add(dr)
End Sub

图3.有细节记录的新订单

  因为CSR同时使用应用程序和更新顾客信息,因此好像任何时候一个CSR看到的都是过期的信息。为了防止这种现象,应用程序的设计师决定dsAllData的数据缓存要每隔30分钟刷新一次,以确保CSR通常看到正确信息。应用程序设计得很仔细,以确保数据刷新只在空闲时段进行,这样它才不影响性能。数据集刷新因此会比30分钟长一点,这依赖于CSR的行为。


图4.应用程序数据模型

  该应用程序的数据模型很简单(图4)。它使用SQL Server 2000存储,只包含三个表,顾客表、订单表、每个订单的细节表,并定义了适当的主键和关系以确保参照的完整性。此外,在OrderDetail上定义了一个触发器来更新Orders 表的Total列。每次插入、更新或者删除一个OrderDetail记录,调用触发器计算该订单的最后销售值,并更新Orders表的适当的行。图5是trg_UpdateOrderTotal触发器的代码:

CREATE TRIGGER trg_UpdateOrderTotal ON [dbo].[OrderDetail]
FOR INSERT, UPDATE, DELETE
AS
 DECLARE @OrderID int
 SELECT @OrderID=OrderID FROM Inserted
 IF @OrderID IS NULL
 SELECT @OrderID=OrderID FROM Deleted
 UPDATE Orders
 SET Total=
 (
  SELECT Sum(Price*Quantity)
  FROM OrderDetail
  WHERE OrderID=@OrderID
 )
 WHERE ID=@OrderID

图5.更新Total列


上一页  1 2 3 4 5  下一页

·"WAP天极之IT新闻资讯,50万元等你拿"    ·天极WAP之游戏狂图,50万元等你下载

天极社区邀请您:写博客日记  上传相片   论坛聊天  订阅电子杂志  推荐网摘   免费图铃工具
笔名:   请您注意:

 遵守国家有关法律、法规,尊重网上道德,承担一切因您的行为而直接或间接引起的法律责任。

 天极网拥有管理笔名和留言的一切权利。
评论:
 

发表评论推荐给朋友我想参加相关培训打印我对此感兴趣订阅电子杂志
相关内容阅读排行榜
  • 使用ADO.NET设计数据库应用程序
  • VIA驱动问题导致DVD刻录失败
  • [配置推荐]学生型闪龙配置
  • 11.10软件精选 FW实用设计
  • 精英主板全面迈进P5时代
  • 详解11月三大硬件杀手游戏及四大凶器
  • 选硬盘 用好希捷互动存储专家
  • NDS十大最受期待游戏
  • 中国星际个人联赛第6轮综述
  • Advertisement