C#数据库入门-008:了解事务

来源:互联网 发布:知敬畏是什么意思 编辑:程序博客网 时间:2024/06/05 16:44

一:何时使用事务
    1: 在批处理过程中,必须把多个行为作为一个单元插入或删除
    2: 只要一个表发生变化,就需要其他表与它同步
    3: 同时修改两个或多个数据库中的数据
    4: 在分布式事务中,在不同服务器上操作数据库中的数据

二:ACID属性:原子性,一致性,孤立性和持续性
    1: 原子性:如果把事务视作单一动作而非各个操作的集合,则它是原子事务。
        只有当所有操作都成功时,事务才成功,并且才会把它提交给数据库。
        如果在事务处理期间有一个操作失败,则认为所有操作都失败,如果操作已经执行,则撤销或回滚。
    2: 一致性:事务无论是否成功的完成,都应该让数据库处于一致状态。
        由事务修改的数据必须符合设置在列上的所有约束,以保持数据的完整性。
    3: 孤立性:每个事务都有明确定义的界限。
        一个事务不应该影响同时运行的其他事务。
        一个事务完成的数据修改必须独立于其他事务完成的数据修改。
        事务要么看到另一并发事务之前处于原来状态的数据,要么看到第二个事务结束后的数据,但看不到中间状态。
    4: 持续性:发生在成功事务内的数据修改将永久保存在系统内,与它们发生的时间无关。
        维护事务日志,如果出现故障,就可以把数据库恢复到其原来的状态。
        完成每个事务时,都在数据库事务日志内对其进行记录。
        如果存在一个主要的系统故障,要求数据库从备份中恢复,将使用这个事务日志插入已经发生的任何成功事务。

三:编写事务的准则
    1: 在事务中不需要用户输入
    2: 如果可能,不要再浏览数据的时候打开事物
    3: 尽量使事物简短
    4: 在事物中最小化访问数据

四:在T-SQL中编写事务
    CREATE PROCEDURE sp_Trans_Test
     @newcustid nchar(5), --三个局部变量
     @newcompname nchar(40),
     @oldcustid nchar(5)
    AS
     DECLARE @inserr int
     DECLARE @delerr int
     DECLARE @maxerr int
     SET @maxerr = 0
    BEGIN TRANSACTION
     INSERT into customers(customerid, companyname) VALUES(@newcustid, @newcompname)
     SET @inserr = @@error --保存语句操作的返回结果
     IF(@inserr > @maxerr)
      SET @maxerr = @inserr
     DELETE FROM customers WHERE customerid = @oldcustid
     SET @delerr = @@error --保存语句操作的返回结果
     IF(@delerr > @maxerr)
      SET @maxerr = @delerr
     IF(@maxerr <> 0)
      BEGIN
       ROLLBACK
       PRINT 'Transaction rolled back'
      END
     ELSE
      BEGIN
       COMMIT
       print 'Transaction committed'
      END
     PRINT 'INSERT error number:' + CAST(@inserr AS NVARCHAR(8))
     PRINT 'DELETE error number:' + CAST(@delerr AS NVARCHAR(8))
     return @maxerr;
    1: EXEC sp_Trans_Test 'dd','dd','z'
        (1 行受影响)
        (0 行受影响)
        Transaction committed
        INSERT error number:0
        DELETE error number:0

    2: EXEC sp_Trans_Test 'dd','dd','z'
        The statement has been terminated.
        (0 行受影响)
        Transaction rolled back
        INSERT error number:2627
        DELETE error number:0

五:在ADO.NET中编写事务
    SqlConnection conn = new SqlConnection(@"server=./sqlexpress; integrated security=true; database=northwind");
    String sqlins = @"INSERT into customers(customerid, companyname) VALUES(@newcustid, @newcompname)";
    String sqldel = @"DELETE FROM customers WHERE customerid = @oldcustid";
    SqlTransaction sqltrans = null;
    try
    {
        conn.Open();

        sqltrans = conn.BeginTransaction();

        SqlCommand cmdins = conn.CreateCommand();
        cmdins.CommandText = sqlins;
        cmdins.Transaction = sqltrans;
        cmdins.Parameters.Add("@newcustid", System.Data.SqlDbType.NVarChar, 5);
        cmdins.Parameters.Add("@newcompname", System.Data.SqlDbType.NVarChar, 30);
        cmdins.Parameters["@newcustid"].Value = textBox1.Text;
        cmdins.Parameters["@newcompname"].Value = textBox2.Text;

        SqlCommand cmddel = conn.CreateCommand();
        cmddel.CommandText = sqldel;
        cmddel.Transaction = sqltrans;
        cmddel.Parameters.Add("@oldcustid", System.Data.SqlDbType.NVarChar, 5);
        cmddel.Parameters["@oldcustid"].Value = textBox3.Text;

        cmdins.ExecuteNonQuery();
        cmddel.ExecuteNonQuery();

        sqltrans.Commit();

        MessageBox.Show("transaction committed");
    }
    catch(Exception ex)
    {
        sqltrans.Rollback();
        conn.Close();
    }

原创粉丝点击