ASP.NET通过使用基于连接的事务对数据库进行操作


使用ASP.NET开发程序时,不仅可以通过Connection对象或者ObjectContext对象实现事务处理,还可以针对SQL Server数据库定义事务,实现对数据的一致性处理从而保证数据的完整性。在通过ADO.NET的事务操作数据库时,任何一个操作都必须成功完成(提交事务),或者所有操作都必须撤销(回滚事务),这样数据库才维持在事务开始之前的状态。 1.方案分析

  在大部分数据库应用程序或网站中,往往存在需要保证其原子性的数据库操作,也就是把这一组操作看成一个整体,如果其中一个操作不成功,那么前面所有操作的结果都将没有意义,而且会造成数据的错误,所以必须将数据恢复到这一组操作开始之前。但有时,硬件故障或其他原因往往会导致这一组操作中的某一环节失败。为了确保这种情况下数据库最终结果的确定性和数据的一致性,绝大多数数据库系统引入了事务机制。

  例如,将资金从一个帐户转移到另一个帐户的银行应用中,一个帐户将一定的金额贷记到一个数据库表中,同时另一个帐户将相同的金额借记到另一个数据库表中。但是在操作的过程中有可能因为意外情况,而导致在一个表中更新了一行,但未能在其他表中更新相应行的情况发生。这种情况是客户最不想看到的。

  如果数据库支持事务,则可以防止上述情况的发生。即将多个数据库操作组合到一个事务中,以防止数据库中出现不一致。当事务中的某一点发生故障,则所有更新都可以回滚到其事务前状态。如果没有发生故障,则通过以完成状态提交事务来完成更新。

  在ADO.NET中,可以在两种事务间进行选择:本地事务和分布式事务。本地事务只涉及一种资源——通常是用户所连接的数据库。开始事务,并把一个或多个命令放在该事务的上下文中,判断整个操作是成功的还是失败的。然后提交该事务,或者退回来重来。分布式事务跨越多个异步资源,并确保要么提交整个事务要么全部撤销,在各个步骤作出的所有修改也是要么全部提交要么全部撤销,分布式事务通过 Microsoft 分布式事务协调程序 (MS DTC) 管理,该协调程序集成了事务中访问的所有资源管理器
  对于本地事务,ADO.NET通过大量数据库专用的事务对象来管理,如SQL Server事务的SqlTransaction。首先产生一个事务,并命令与它关联,然后决定结果。对于分布式事务,需要企业服务(Enterprise Server)和被服务的组件。

  注意:建议用户只在分布式事务中执行更新、插入和删除,因为这些操作会占用大量的数据库资源。选择语句可能会对数据库资源进行不必要的锁定,在某些方案中,可能需要使用事务进行选择。

  事务多用于控制和维护数据库中每个操作的一致性和整体性,而不管系统中可能发生的错误。

  在ADO.NET中可通过连接类的BeginTransaction方法创建一个全新的的本地事务。可以为该事务赋一个名称和一个隔离级(关于事务的隔离级请参见本节的补充说明)。假设把该方法映射到BEGIN TRANSACTION的SQL Server实现,则创建事务过程的基本方法如下。

  (1)BeginTransaction方法

  开始数据库事务,其语法格式如下:

  public SqlTransaction BeginTransaction ()

  返回值:表示新事务对象。

  (2)Transaction属性

  获取或设置将在其中执行SqlCommand的SqlTransaction。

  public SqlTranssction Transaction { get; set; }

  属性值:SqlTranssction默认值为空引用。

  (3)Commit方法

  提交数据库事务,其语法格式如下:

  public override void Commit()

  (4)Rollback方法

  从挂起状态回滚事务,其语法格式如下:

  public override void Rollback()

  说明:在以上方法中为了向事务添加命令回滚,设置了命令对象的Transaction属性。但如果把一个命令对象的Transaction属性设置到了一个不是连接到同一个连接的事务对象,在试图执行一个语句时将会抛出一个异常。一旦所有的命令完成执行,调用事务对象的Commit方法完成,或者调用Rollback方法撤销该事务,并回滚所有的变更
通过使用Commit或Rollback方法,可显式地终止一个事务。SqlTransaction类支持事务中有名称的保存点(named savepoint),用它可以恢复事务的某一部分。有名称的保存点利用一个特定的SQL Server特性:SAVE TRANSACTION语句。

  2.实施过程

  在ASP.NET中,有两种方法可以实现事务。具体方法及其实施过程如下。

  在网站后台管理中对网站进行维护与更新时,免不了要执行向多个数据表中同时插入数据的操作。本实例就是在向数据库的3个表中插入数据时引入事务,确保了插入数据最终结果的确定性和数据的一致性。

  单击图中的【添加】按钮,程序将会向数据库中的3个数据表同时添加数据,当在执行添加的过程中因某种原因造成了程序的终止,则该程序将恢复到添加之前的状态,数据添加无效。

  具体实施过程:

  (1)新建一个网站,将其命名为13,默认主页为Default.aspx。

  (2)在Default.aspx页中添加9个TextBox控件和两个Button控件,分别用于输入要添加的数据信息、执行添加操作和清空文本框信息。

  (3)触发Default.aspx页面中的【添加】按钮的Click事件,在该事件中完成向数据库添加数据操作并引入事务,主要程序代码如下。

protectedvoidButton1_Click(objectsender,EventArgse)
  {
    if(TextBox1.Text==""||TextBox2.Text==""||TextBox3.Text=="" 
||TextBox4.Text==""||TextBox5.Text==""||TextBox6.Text== 
""||TextBox7.Text==""||TextBox8.Text==""||TextBox9.Text=="")
    {
      Response.Write("<scriptlanguage=javascript>alert('不允许输入空数据!');
location='javascript:history.go(-1)'</script>");
    }
    SqlConnectioncon=newSqlConnection("server=(local);userid
=sa;pwd=;DataBase=db_07");
    con.Open();
    //通过SqlConnection的BeginTransaction方法创建名为st的对象Transaction
    SqlTransactionst=con.BeginTransaction();
    SqlCommandcom=con.CreateCommand();
    //将SqlTransaction对象分配给SqlCommand对象的Transaction属性
    com.Transaction=st;
    try
    {
      //向表1插入数据
      com.CommandText="insertintotb_21a(name,age,sex)values('"+ 
TextBox1.Text+"','"+TextBox2.Text+"','"+TextBox3.Text+"')";
      com.ExecuteNonQuery();
      //向表2插入数据
      com.CommandText="insertintotb_21b(name,age,sex)values('"+
TextBox4.Text+"','"+TextBox5.Text+"','"+TextBox6.Text+"')";
      com.ExecuteNonQuery();
      //向表3插入数据
      com.CommandText="insertintotb_21c(name,age,sex)values('"+TextBox7.
Text+"','"+TextBox8.Text+"','"+TextBox9.Text+"')";
      com.ExecuteNonQuery();
      //提交事物
      st.Commit();
      Response.Write("<scriptlanguage=javascript>alert('添加成功!');
location='javascript:history.go(-1)'</script>");
    }
    catch(Exceptionerror)
    {
      //回滚事物
      st.Rollback();
    }
   finally
    {
      con.Close();
    }
}

  注意:在编写代码前,不要忘记先引用using System.Data.SqlClient命名空间。 方案实施二,通过在存储过程中使用事务对数据库进行操作


« 
» 
快速导航

Copyright © 2016 phpStudy | 豫ICP备2021030365号-3