在ADO.NET中使用事务保护数据的完整性(5)

原创 2004年06月14日 15:17:00

 

使用Savepoints

当使用savepoints, 记住仅仅是回滚savepoints并不是足够的.当局部回滚后事务必须仍被提交.同时,如果你选择实施它们,如何通知用户或处理局部完成事务是非常重要的.

接下来的代码描述创建一个新的客户,同时处理客户请求.你不得不执行慢的连接,或某些原因在检查库以前的操作库存等级成本是被禁止的.时间的99.9%整个过程应该被成功结束.然而,如果在SiteInventory表 保持最小的库存等级限制,它将会失败.你可以看一下的代码:

using System;

using System.Drawing;

using System.Collections;

using System.ComponentModel;

using System.Windows.Forms;

using System.Data;

using System.Data.SqlClient;

using System.Data.SqlTypes;

 

…public void SavepointTransaction()

{

   // Create and open the connection.

   SqlConnection conn = new SqlConnection();

   string connString = "Server= SqlInstance;Database=Test;"

      + "Integrated Security=SSPI";

   conn.ConnectionString = connString;

   conn.Open();

 

   // Create the commands.

   // cmdInsertCustomer creates a new customer record

   // by calling the DebitWarehouseInventory

   // stored procedure.

   SqlCommand cmdInsertCustomer =

      new SqlCommand("CreateCustomer", conn);

   cmdInsertCustomer.CommandType = CommandType.StoredProcedure;

   cmdInsertCustomer.Parameters.Add

      ("@FirstName", SqlDbType.NVarChar, 50, "FirstName");

   cmdInsertCustomer.Parameters.Add

      ("@LastName", SqlDbType.NVarChar, 50, "LastName");

   cmdInsertCustomer.Parameters.Add

      ("@Email", SqlDbType.NVarChar, 50, "Email");

   cmdInsertCustomer.Parameters.Add("@CID", SqlDbType.Int, 0);

   cmdInsertCustomer.Parameters["@FirstName"].Direction =

      ParameterDirection.Input;

   cmdInsertCustomer.Parameters["@LastName"].Direction =

      ParameterDirection.Input;

   cmdInsertCustomer.Parameters["@Email"].Direction =

      ParameterDirection.Input;

   cmdInsertCustomer.Parameters["@CID"].Direction =

      ParameterDirection.Output;

 

   // cmdRequestMaterials creates a pick list

   // of the materials requested by the customer

   // by calling the InsertMaterialsRequest

   // stored procedure.

   SqlCommand cmdRequestMaterials =

      new SqlCommand("InsertMaterialsRequest", conn);

   cmdRequestMaterials.CommandType = CommandType.StoredProcedure;

   cmdRequestMaterials.Parameters.Add

      ("@CustomerID", SqlDbType.Int, 0, "CustomerId");

   cmdRequestMaterials.Parameters.Add

      ("@RequestPartID", SqlDbType.Int, 0, "PartId");

   cmdRequestMaterials.Parameters.Add

      ("@Number", SqlDbType.Int, 0, "NumberRequested");

   cmdRequestMaterials.Parameters["@CustomerID"].Direction =

      ParameterDirection.Input;

   cmdRequestMaterials.Parameters["@RequestPartID"].Direction =

      ParameterDirection.Input;

   cmdRequestMaterials.Parameters["@Number"].Direction =

      ParameterDirection.Input;

 

   // cmdUpdateSite debits the requested materials

   // from the inventory of those available by calling

   // the UpdateSiteInventory stored procedure.

   SqlCommand cmdUpdateSite =

      new SqlCommand("UpdateSiteInventory", conn);

   cmdUpdateSite.CommandType = CommandType.StoredProcedure;

   cmdUpdateSite.Parameters.Add

      ("@SiteID", SqlDbType.Int, 0, "SiteID");

   cmdUpdateSite.Parameters.Add

      ("@SitePartID", SqlDbType.Int, 0, "PartId");

   cmdUpdateSite.Parameters.Add

      ("@Debit", SqlDbType.Int, 0, "Debit");

   cmdUpdateSite.Parameters["@SiteID"].Direction =

      ParameterDirection.Input;

   cmdUpdateSite.Parameters["@SitePartID"].Direction =

      ParameterDirection.Input;

   cmdUpdateSite.Parameters["@Debit"].Direction =

      ParameterDirection.Input;

        

   // Begin the transaction and enlist the commands.

   SqlTransaction tran = conn.BeginTransaction();

   cmdInsertCustomer.Transaction = tran;

   cmdUpdateSite.Transaction  = tran;

   cmdRequestMaterials.Transaction  = tran;

 

   try

   {

      // Execute the commands.

      cmdInsertCustomer.Parameters["@FirstName"].Value

         = "Mads";

      cmdInsertCustomer.Parameters["@LastName"].Value

         = "Nygaard";

      cmdInsertCustomer.Parameters["@Email"].Value

         = "MadsN@AdventureWorks.com";

      cmdInsertCustomer.ExecuteNonQuery();

 

      tran.Save("Customer");

 

      cmdRequestMaterials.Parameters["@CustomerID"].Value

         = cmdInsertCustomer.Parameters["@CID"].Value;

      cmdRequestMaterials.Parameters["@RequestPartID"].Value

         = 3;

      cmdRequestMaterials.Parameters["@Number"].Value

         = 22;

      cmdRequestMaterials.ExecuteNonQuery();

 

      cmdUpdateSite.Parameters["@SitePartID"].Value

         = 3;

      cmdUpdateSite.Parameters["@Debit"].Value

         = 22;

      cmdUpdateSite.Parameters["@SiteID"].Value

         = 4;

      cmdUpdateSite.ExecuteNonQuery();

 

      // Commit the transaction.

      tran.Commit();

 

   }

   catch(SqlException sqlEx)

   {

      try

      {

         // Roll back the transaction

         // to the savepoint.

         Console.WriteLine(sqlEx.Message);

         tran.Rollback("Customer");

         tran.Commit();

 

         // Add code to notify user or otherwise handle

         // the fact that the procedure was only

         // partially successful.

      }

      catch(SqlException ex)

      {

         // If the partial rollback fails,

         // roll back the whole transaction.

         Console.WriteLine(ex.Message);

         tran.Rollback();

 

         // Additional error handling if needed.

      }

   }

   finally

   {

      // Close the connection.

      conn.Close();

   }

}

使用内嵌事务

内嵌事务如savepoints一样考虑同样的注意事项.为了确认局部回滚仍然需要提交,处理局部完成过程.

以下的代码示例描述创建一个新的订单,同时创建了订单项目. 如果创建订单列表失败-可能是PartID无效的对于选择的位置来说-你仍然需要进入订单,在其它方面选取. 内嵌的try/catch 块封装了内嵌事务用来处理选取列表,允许内部事务提交或失败依赖于外部的事务.外部的catch 块回滚整个事务如果订单创建过程失败.

using System;

using System.Drawing;

using System.Collections;

using System.ComponentModel;

using System.Windows.Forms;

using System.Data;

using System.Data.OleDb;

using System.Text;

…public void NestedTransaction(string UID, string pwd)

{

   // Create and open the connection.

   OleDbConnection conn = new OleDbConnection();

   StringBuilder sb = new StringBuilder();

   sb.Append("Jet OLEDB:System database=");

            sb.Append(@"C:/Databases/system.mdw;");

            sb.Append(@"Data Source=C:/Databases/orders.mdb;");

            sb.Append("Provider=Microsoft.Jet.OLEDB.4.0;");

            sb.Append("User ID=" + UID + ";Password=" + pwd);

   string connString = sb.ToString();

   conn.ConnectionString = connString;

   conn.Open();

 

   // Create the commands.

   string cmdString = "Insert into Orders"

      + " (OrderID, OrderDate, CustomerID)"

      + " values('ABC60', #4/14/04#, 456)";

   OleDbCommand cmdInsertOrder = new OleDbCommand(cmdString,conn);

 

   //No need to insert OrderLineID, as that is an AutoNumber field.

   cmdString = "Insert into OrderLines (OrderID, PartID, Quantity)"

      + " values('ABC60', 25, 10)";

   OleDbCommand cmdInsertOrderLine =

new OleDbCommand(cmdString,conn);

 

   cmdString = "Insert into PickList (OrderID, PartID, Quantity)"

      + " values('ABC60', 25, 10)";

   OleDbCommand cmdCreatePickList =

new OleDbCommand(cmdString,conn);

 

   // Begin the outer transaction and

   // enlist the order-related commands.

      OleDbTransaction tran = conn.BeginTransaction();

   cmdInsertOrder.Transaction = tran;

   cmdInsertOrderLine.Transaction = tran;

           

   try

   {

      // Execute the commands

      // to create the order and order

      // line items.

      cmdInsertOrder.ExecuteNonQuery();

      cmdInsertOrderLine.ExecuteNonQuery();

 

      // Create a nested transaction

      // that allows the pick list

      // creation to succeed or fail

      // separately if necessary.

      OleDbTransaction nestedTran = tran.Begin();

           

      // Enlist the pick list command.

      cmdCreatePickList.Transaction = nestedTran;

 

      try

      {

 

         // Execute the pick list command.

         cmdCreatePickList.ExecuteNonQuery();

 

         // Commit the nested transaction.

         nestedTran.Commit();

      }

      catch(OleDbException ex)

      {

         //Roll back the transaction.

         nestedTran.Rollback();

 

         // Add code to notify user or otherwise handle

         // the fact that the procedure was only

         // partially successful.

      }

 

      // Commit the outer transaction.

      tran.Commit();

   }

   catch(OleDbException ex)

   {

      //Roll back the transaction.

      tran.Rollback();

 

      //Additional error handling if needed.

   }

   finally

   {

      // Close the connection.

      conn.Close();

   }

}

注: 引擎提供者为Microsoft OLE DB,其支持内嵌事务.

总结

事务是一个强有力的方式,用来保证数据修改任务得到合适的处理,同时ado.net让我们处理数据存取的能力更容易.当你构建你的数据读取和使用方案的时候考虑到这些情况,你将会保证你数据的完整性.

确保事务完整性

确保数据完整性 一、认识约束 约束是数据库中保证数据库里表中数据完整性的手段。录入数据库中的数据都有实际的意义,而约束的作用就是保证数据在实际业务中是有意义的,也就是减少脏数据的机会。   1....
  • u012027907
  • u012027907
  • 2013年10月02日 14:40
  • 1642

HTTP+ 加密 + 认证 + 完整性保护 =HTTPS

早上起来看了会书,虽然一遍可能不会完全学会,但是还是希望能学多少学多少,  1.HTTP+ 加密 + 认证 + 完整性保护 =HTTPS  如果在 HTTP 协议通信过程中使用未经加密的明文,比如...
  • qq_33413264
  • qq_33413264
  • 2017年06月13日 10:14
  • 361

C# ADO.Net事务处理

SQL Server中的事务可以将多个数据库增删改查操作合并为单个工作单元,在操作过程中任何部分出错都可以滚回已经执行的所有更改.ADO.Net中也提供了事务处理功能,通过ADO.net事务,可以将多...
  • miniduhua
  • miniduhua
  • 2016年10月21日 14:23
  • 3254

保证数据完整性

数据库能防止存储垃圾数据,而我们所使用的RDBMS实现该功能主要是通过维护数据完整性来实现。那么,根据数据完整性实施的方法,我们可以分为哪几类呢? 实体完整性,在某种意义上,实体的存在是独立于数据库...
  • cdgylijun
  • cdgylijun
  • 2016年01月04日 18:51
  • 522

ADO.NET 事务控制

在ADO.NET 中,可以使用Connection 和Transaction 对象来控制事务。若要执行事务,请执行下列操作: 1.调用Connection 对象的BeginTransactio...
  • suixufeng
  • suixufeng
  • 2013年10月12日 10:11
  • 972

.NET开发中的事务处理大比拼 之 ADO.NET级别的事务

现在我们对事务的概念和原理都有所了解了,并且作为已经有一些基础的C#开发者,我们已经熟知编写数据库交互程序的一些要点,即:(1)使用SqlConnection类的对象的Open()方法建立与数据库服务...
  • sven_xu
  • sven_xu
  • 2015年06月02日 09:13
  • 1213

【Android数据加密与完整性校验之RSA加密算法】Android应用开发中如何使用RSA加密算法对数据进行校验

转载自:http://blog.csdn.net/i2cbus/article/details/42043957       这个世界很精彩,这个世界很无奈。是的,在互联网时代,如何保护自己...
  • cangchen
  • cangchen
  • 2015年03月04日 11:48
  • 730

如何禁用 Mac OS X 的系统完整性保护

Mac OS X 10.11 El Capitan 系统默认开启了完整性保护(System Intregrity Protection,SIP),所以即使是root帐户也无法修改系统目录中的文件,如/...
  • testcs_dn
  • testcs_dn
  • 2017年06月27日 20:39
  • 1692

通过加密算法实现数据的完整性、机密性及身份验证

一般互联网上加密算法分为三种:                 对称加密、单向加密、非对称加密 下面就来介绍下如何通过上面的三种加密算法实现数据的机密性、完整性及身份验证。 对称机密算法: ...
  • lyglostangel
  • lyglostangel
  • 2015年05月15日 07:50
  • 3656

Java 保证数据的完整性

第三章  保证数据的完整性   一、数据完整性的分类 1、实体完整性          ------ 保证一行数据是有效的          表中的一行数据如果与它所代表的实体完全一致,则具...
  • yanyan265
  • yanyan265
  • 2015年10月25日 16:37
  • 461
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:在ADO.NET中使用事务保护数据的完整性(5)
举报原因:
原因补充:

(最多只允许输入30个字)