zoukankan      html  css  js  c++  java
  • sqlserver shiwu

    一 事务处理介绍
    事务是这样一种机制,它确保多个SQL语句被当作单个工作单
    元来处理。事务具有以下的作用:
    * 一致性:同时进行的查询和更新彼此不会发生冲突,其他
    用户不会看到发生了变化但尚未提交的数据。
    * 可恢复性:一旦系统故障,数据库会自动地完全恢复未完
    成的事务。

    二 事务与一致性
    事务是完整性的单位,一个事务的执行是把数据库从一个一
    致的状态转换成另一个一致的状态。因此,如果事务孤立执行时
    是正确的,但如果多个事务并发交错地执行,就可能相互干扰,
    造成数据库状态的不一致。在多用户环境中,数据库必须避免同
    时进行的查询和更新发生冲突。这一点是很重要的,如果正在被
    处理的数据能够在该处理正在运行时被另一用户的修改所改变,
    那么该处理结果是不明确的。
    不加控制的并发存取会产生以下几种错误:
    1 丢失修改(lost updates)
    当多个事务并发修改一个数据时,不加控制会得出错误的结
    果,一个修改会覆盖掉另一个修改。
    2 读的不可重复性
    当多个事务按某种时间顺序存取若干数据时,如果对并发存
    取不加控制,也会产生错误。
    3 脏读(DIRDY DATA),读的不一致性
    4 光标带来的当前值的混乱
    事务在执行过程中它在某个表上的当前查找位置是由光标表
    示的。光标指向当前正处理的记录。当处理完该条记录后,则指
    向下一条记录。在多个事务并发执行时,某一事务的修改可能产
    生负作用,使与这些光标有关的事务出错。
    5 未释放修改造成连锁退出
    一个事务在进行修改操作的过程中可能会发生故障,这时需
    要将已做的修改回退(Rollback)。如果在已进行过或已发现错
    误尚未复原之前允许其它事务读已做过修改(脏读),则会导致
    连锁退出。
    6 一事务在对一表更新时,另外的事务却修改或删除此表的
    定义。
    数据库会为每个事务自动地设置适当级别的锁定。对于前面
    讲述的问题:脏读、未释放修改造成的连锁退出、一事务在对一
    表更新时另外的事务却修改或删除此表的定义,数据库都会自动
    解决。而另外的三个问题则需要在编程过程中人为地定义事务或
    加锁来解决。
    三 事务和恢复
    数据库本身肩负着管理事务的责任。事务是最小的逻辑工作
    单元,在这个工作单元中,对数据库的所有更新工作,要么必须
    全部成功,要么必须全部失败(回退)。只要应用程序指定了某
    段程序为一个事务并做了相应的处理(提交或回退),数据库系
    统会自动维护事务本身的特性。

    事务处理的定义

    在许多大型、关键的应用程序中,计算机每秒钟都在执行大量的任务。更为经常的不是这些任务本身,而是将这些任务结合在一起完成一个业务要求,称为事务。如果能成功地执行一个任务,而在第二个或第三个相关的任务中出现错误,将会发生什么?这个错误很可能使系统处于不一致状态。这时事务变得非常重要,它能使系统摆脱这种不一致的状态。
           首先,让我们看一看什么是事务处理。
    19.1 事务处理的定义
        本书已经介绍了许多涉及事务处理的概念,但是事务处理到底是什么。在大型机时代,就有事务处理。用户信息控制系统(CICS)、Tuxedo和TopEnd等产品都是事务处理系统的例子,它们为应用程序提供事务服务。
        为了讨论事务处理,必须首先定义事务。
        事务是一个最小的工作单元,不论成功与否都作为一个整体进行工作。
        不会有部分完成的事务。由于事务是由几个任务组成的,因此如果一个事务作为一个整体是成功的,则事务中的每个任务都必须成功。如果事务中有一部分失败,则整修事务失败。
        当事务失败时,系统返回到事务开始前的状态。这个取消所有变化的过程称为“回滚”( rollback )。例如,如果一个事务成功更新了两个表,在更新第三个表时失败,则系统将两次更新恢复原状,并返回到原始的状态。
    19.1.1 保持应用程序的完整性
        任何应用程序的关键是要确保它所执行的所有操作都是正确的,如果应用程序仅仅是部分地完成操作,那么应用程序中的数据,甚至整个系统将会处于不一致状态。例如,看一下银行转账的例子,如果从一个帐户中提出钱,而在钱到达另一个帐户前出错,那么在此应用
    程序中的数据是错误的,而且失去了它的完整性,也就是说钱会莫名其妙地消失。
        克服这种错误有两种方法:
        ? 在传统的编程模型中,开发者必须防止任何方式的操作失败。对任何失败点,开发者必须加上支持应用程序返回到这一操作开始前的状态的措施。换句话说,开发者必须加入代码使系统能够在操作出现错误时恢复原状(撤消)。
        ? 更为简单的方法是在事务处理系统的环境之内进行操作,事务处理系统的任务就是保证整个事务或者完全成功,或者什么也不做。如果事务的所有任务都成功地完成,那么在应用程序中的变化就提交给系统,系统就处理下一个事务或任务。如果操作中某一部分不能成功地完成,这将使系统处于无效的状态,应回滚系统的变化,并使应用程序返回到原来的状态。
        事务处理系统的能力就是将完成这些操作的知识嵌入到系统本身。开发者不必为将系统恢复原状编写代码,需要做的只是告诉系统执行任务是否成功,剩下的事情由事务处理系统自动完成。
        在帮助开发人员解决复杂的问题时,事务处理系统的另一好处是其ACID属性。
    19.1.2 ACID属性
        当事务处理系统创建事务时,将确保事务有某些特性。组件的开发者们假设事务的特性应该是一些不需要他们亲自管理的特性。这些特性称为ACID特性。
        ACID就是:原子性(Atomicity )、一致性( Consistency )、隔离性( Isolation)和持久性(Durabilily)。
        1. 原子性
        原子性属性用于标识事务是否完全地完成,一个事务的任何更新要在系统上完全完成,如果由于某种原因出错,事务不能完成它的全部任务,系统将返回到事务开始前的状态。
        让我们再看一下银行转帐的例子。如果在转帐的过程中出现错误,整个事务将会回滚。只有当事务中的所有部分都成功执行了,才将事务写入磁盘并使变化永久化。
        为了提供回滚或者撤消未提交的变化的能力,许多数据源采用日志机制。例如,SQL Server使用一个预写事务日志,在将数据应用于(或提交到)实际数据页面前,先写在事务日志上。但是,其他一些数据源不是关系型数据库管理系统(RDBMS),它们管理未提交事务的方式完全不同。只要事务回滚时,数据源可以撤消所有未提交的改变,那么这种技术应该可用于管理事务。
        2. 一致性
        事务在系统完整性中实施一致性,这通过保证系统的任何事务最后都处于有效状态来实现。如果事务成功地完成,那么系统中所有变化将正确地应用,系统处于有效状态。如果在事务中出现错误,那么系统中的所有变化将自动地回滚,系统返回到原始状态。因为事务开
    始时系统处于一致状态,所以现在系统仍然处于一致状态。
        再让我们回头看一下银行转帐的例子,在帐户转换和资金转移前,帐户处于有效状态。如果事务成功地完成,并且提交事务,则帐户处于新的有效的状态。如果事务出错,终止后,帐户返回到原先的有效状态。
        记住,事务不负责实施数据完整性,而仅仅负责在事务提交或终止以后确保数据返回到一致状态。理解数据完整性规则并写代码实现完整性的重任通常落在开发者肩上,他们根据业务要求进行设计。
        当许多用户同时使用和修改同样的数据时,事务必须保持其数据的完整性和一致性。因此我们进一步研究A C I D特性中的下一个特性:隔离性。
        3. 隔离性
        在隔离状态执行事务,使它们好像是系统在给定时间内执行的唯一操作。如果有两个事务,运行在相同的时间内,执行相同的功能,事务的隔离性将确保每一事务在系统中认为只有该事务在使用系统。
        这种属性有时称为串行化,为了防止事务操作间的混淆,必须串行化或序列化请求,使得在同一时间仅有一个请求用于同一数据。
        重要的是,在隔离状态执行事务,系统的状态有可能是不一致的,在结束事务前,应确保系统处于一致状态。但是在每个单独的事务中,系统的状态可能会发生变化。如果事务不是在隔离状态运行,它就可能从系统中访问数据,而系统可能处于不一致状态。通过提供事
    务隔离,可以阻止这类事件的发生。
        在银行的示例中,这意味着在这个系统内,其他过程和事务在我们的事务完成前看不到我们的事务引起的任何变化,这对于终止的情况非常重要。如果有另一个过程根据帐户余额进行相应处理,而它在我们的事务完成前就能看到它造成的变化,那么这个过程的决策可能
    建立在错误的数据之上,因为我们的事务可能终止。这就是说明了为什么事务产生的变化,直到事务完成,才对系统的其他部分可见。
        隔离性不仅仅保证多个事务不能同时修改相同数据,而且能够保证事务操作产生的变化直到变化被提交或终止时才能对另一个事务可见,并发的事务彼此之间毫无影响。这就意味着所有要求修改或读取的数据已经被锁定在事务中,直到事务完成才能释放。大多数数据库,例如SQL Server以及其他的RDBMS,通过使用锁定来实现隔离,事务中涉及的各个数据项或数据集使用锁定来防止并发访问。
        4. 持久性
        持久性意味着一旦事务执行成功,在系统中产生的所有变化将是永久的。应该存在一些检查点防止在系统失败时丢失信息。甚至硬件本身失败,系统的状态仍能通过在日志中记录事务完成的任务进行重建。持久性的概念允许开发者认为不管系统以后发生了什么变化,完
    成的事务是系统永久的部分。
        在银行的例子中,资金的转移是永久的,一直保持在系统中。这听起来似乎简单,但这,依赖于将数据写入磁盘,特别需要指出的是,在事务完全完成并提交后才写入磁盘的。
        所有这些事务特性,不管其内部如何关联,仅仅是保证从事务开始到事务完成,不管事务成功与否,都能正确地管理事务涉及的数据。

    *****************************************************

    Ado.Net事务处理。
    在ADO.NET 中,可以使用Connection 和Transaction 对象来控制事务。若要执行事务,请执行下列操作:
    • 调用Connection 对象的BeginTransaction 方法来标记事务的开始。
    • 将Transaction 对象分配给要执行的Command的Transaction 属性。
    • 执行所需的命令。
    • 调用Transaction 对象的Commit 方法来完成事务,或调用Rollback 方法来取消事务。
    当然ADO.NET事务处理有优点和缺点,运用起来看具体情况了。
    • 优点:
    – 简单性
    – 和数据据事务差不多的快
    – 独立于数据库,不同数据库的专有代码被隐藏了
    • 缺点:
    – 事务不能跨越多个数据库连接
    – 事务执行在数据库连接层上,所以需要在事务过程中维护一个数据库连接。

    下边我们看一个例子,建立一个页面,同样简单,只需要一个按钮,然后编程:

    1using System;
    2using System.Data;
    3using System.Configuration;
    4using System.Collections;
    5using System.Web;
    6using System.Web.Security;
    7using System.Web.UI;
    8using System.Web.UI.WebControls;
    9using System.Web.UI.WebControls.WebParts;
    10using System.Web.UI.HtmlControls;
    11using System.Data.SqlClient;
    12
    13namespace WebApplication1
    14{
    15 public partial class AdoAction : System.Web.UI.Page
    16 {
    17 protected void Page_Load(object sender, EventArgs e)
    18 {
    19
    20        }
    21
    22 protected void btn_Click(object sender, EventArgs e)
    23 {
    24            SqlConnection con = new SqlConnection();
    25            con.ConnectionString=ConfigurationManager.ConnectionStrings["DSN"].ConnectionString;
    26            con.Open();
    27 //启动一个事务。
    28            SqlTransaction myTran = con.BeginTransaction();
    29 //为事务创建一个命令,注意我们执行双条命令,第一次执行当然成功。我们再执行一次,失败。
    30 //第三次我们改其中一个命令,另一个不改,这时候事务会报错,这就是事务机制。
    31            SqlCommand myCom = new SqlCommand();
    32            myCom.Connection = con;
    33            myCom.Transaction = myTran;
    34 try
    35 {
    36                myCom.CommandText = "insert into SqlAction values ('测试2','111')";
    37                myCom.ExecuteNonQuery();
    38                myCom.CommandText = "insert into SqlAction values ('测试3','111')";
    39                myCom.ExecuteNonQuery();
    40                myTran.Commit();
    41                Response.Write("成功执行");
    42
    43            }
    44 catch (Exception Ex)
    45 {
    46                myTran.Rollback();
    47 //创建并且返回异常的错误信息
    48                Response.Write(Ex.ToString());
    49                Response.Write("写入数据库失败");
    50            }
    51 finally
    52 {
    53                con.Close();
    54            }
    55
    56        }
    57
    58
    59    }
    60}

    事务处理需要一个数据库连接以及一个事务处理对象。在SQL Server和ADO.NET中使用事务处理的难点在于SqlTransaction类。此类名称随所使用的数据库平台的不同而会有一些变化。例如,对于OLEDB数据库来说,事务处理类名为OleDbTransaction。

    System.Data.SqlClient namespace包括了SqlTransaction类。此类包括了两个属性:

    Connection:指示同事务处理相关联的SqlConnection对象;

    IsolationLevel:定义事务处理的IsolationLevel。

    属性IsolationLevel是包括如下成员的枚举对象:

    Chaos:从高度独立的事务处理中出现的pending changes不能被覆盖;

    ReadCommitted:当数据需要被非恶意读取时,采用共享锁定(shared locks),但数据仍然可以在事务处理结束时被更新,这造成了非重复性的数据读取(nonrepeatable reads)或phantom data的产生;

    ReadUncommitted:恶意读取数据是可能发生的,这表示没有使用共享锁定(shared locks),并且没有实现独占锁定(exclusive locks);

    RepeatableRead:锁定查询中所用到的所有数据,由此避免其他用户对数据进行更新。在phantom rows仍然可用的状态下,这可以避免非重复性的数据读取(nonrepeatable reads);

    Serialisable:在DataSet中进行范围锁定,由此防止其他用户在事务处理结束之前更新数据或在数据库中插入行;

    IsolationLevel定义锁定记录的级别,但这一概念不在本文论述范围之内。对象SqlTransaction也提供了类似的方法。你可以使用以下方法来进行事务处理:

    Commit:提交数据库事务处理;

    Rollback:从未决状态(pending state)反转(roll back)事务处理。事务处理一旦被提交后即不能执行此操作;

    Save:在事务处理中创建savepoint可以对事务处理的一部分进行反转,并且指定savepoint名称。

    以下的C#示例将这些部分综合起来。

    这一简单的控制台程序将通过以下步骤将两行插入到Northwind数据库的表格中:

    调用Connection对象的BeginTransaction方法以标记事务处理的起始位置。BeginTransaction方法对事务处理返回了一个坐标(reference),此坐标被指定给事务处理所用到的Command对象。

    将Transaction对象指定给将要执行的Command的Transaction属性。如果某Command在活动Transaction中的Connection上被执行,并且Transaction对象还没有被指定到Command的Transaction属性,则会产生一个异常。

    调用Transaction对象的Commit方法来结束事务处理,或者调用Rollback方法来取消事务处理。

    等价的VB.NET代码与之类似。

    事务处理结束

    尽管这是一个简单的示例,但它还是充分显示了在.NET应用程序中使用事务处理是多么的简单。请记住,事务处理只有在处理一组命令时才是必要的。

    在数据库连接上创建事务处理对象,然后调用事务处理对象来提交事务或回滚事务。简单的代码:
    private void button1_Click(object sender, System.EventArgs e)
    {
       SqlConnection conn = new SqlConnection("Data Source=192.168.2.200;uid=sa; password=;database = HaierHR");
       conn.Open();
    //启用事务
       SqlTransaction tran = conn.BeginTransaction();
       SqlCommand cmd = new SqlCommand();
       cmd.Connection = conn;
       cmd.Transaction = tran;
    try
    {
        cmd.CommandText = "UPDATE HRRollMain Set TotalMember=TotalMember-100 WHERE RollID = '2005070101'";
        cmd.ExecuteNonQuery();
        cmd.CommandText = "UPDATE HRRollSum Set TotalSumMember=TotalSumMember+100 WHERE RollSumID = '20050701'";
        cmd.ExecuteNonQuery();
        tran.Commit();
        MessageBox.Show("事务提交成功!");
       }
    catch(Exception ex)
    {
        tran.Rollback();
        MessageBox.Show("Error!"+ex.Message);
       }
      }

  • 相关阅读:
    Linux(centos7)安装maven3.5
    mysql安装错误之->ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)
    CentOS7 安装tomcat为系统服务器 Systemctl管理Tomcat,并设置开机启动
    linux(centos)设置tomcat开机启动
    linux(centos7)安装tomcat
    修改Tomcat8w.exe可执行路径:Path to executable
    CentOS 7更改yum源与更新系统
    最全的PHP开发Android应用程序
    Cookies的各方面知识(基础/高级)深度了解
    使用Hash直接登录Windows(HASH传递)
  • 原文地址:https://www.cnblogs.com/axyz/p/1978273.html
Copyright © 2011-2022 走看看