zoukankan      html  css  js  c++  java
  • 使用快照隔离snapshot isolation实例(二)

    示例

    以下示例演示修改数据时的快照隔离行为。该代码执行下列操作:

    • 连接到 AdventureWorks 示例数据库并启用 SNAPSHOT 隔离。

    • 创建一个名为 TestSnapshotUpdate 的表并插入三行示例数据。

    • 使用 SNAPSHOT 隔离开始但是不完成 sqlTransaction1。在事务中选择三行数据。

    • 创建第二个与 AdventureWorks 的 SqlConnection,并使用 READ COMMITTED 隔离级别创建第二个事务,更新在 sqlTransaction1 中选择的其中一行的值。

    • 提交 sqlTransaction2。

    • 返回 sqlTransaction1 并尝试更新 sqlTransaction2 已提交的相同的行。将引发 3960 错误,sqlTransaction1 将自动回滚。控制台窗口中将显示 SqlException.Number 和 SqlException.Message。

    • 执行清理代码以禁用 AdventureWorks 中的快照隔离并删除 TestSnapshotUpdate 表。

    View Code
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Data.SqlClient;
    using System.Data;
    namespace snapshot2
    {
        class Program
        {
            static void Main(string[] args)
            {
                string connectionString = @"Data Source=XUWEI/SQLEXPRESS;Initial Catalog=AdventureWorks;User ID=sa;Password=sa12345";
                using (SqlConnection connection1 = new SqlConnection(connectionString))
                {
                    connection1.Open();
                    SqlCommand command1 = connection1.CreateCommand();
                    // Enable Snapshot isolation in AdventureWorks,设置数据库使其支持快照隔离(Snapshot isolation)技术。
                    command1.CommandText =
                        "ALTER DATABASE AdventureWorks SET ALLOW_SNAPSHOT_ISOLATION ON";
                    try
                    {
                        command1.ExecuteNonQuery();
                        Console.WriteLine(
                            "Snapshot Isolation turned on in AdventureWorks.");
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("ALLOW_SNAPSHOT_ISOLATION ON failed: {0}", ex.Message);
                    }
                    // Create a table ,创建表格。
                    command1.CommandText =
                        "IF EXISTS "
                        + "(SELECT * FROM sys.tables "
                        + "WHERE name=N'TestSnapshotUpdate')"
                        + " DROP TABLE TestSnapshotUpdate";
                    command1.ExecuteNonQuery();
                    command1.CommandText =
                        "CREATE TABLE TestSnapshotUpdate "
                        + "(ID int primary key, CharCol nvarchar(100));";
                    try
                    {
                        command1.ExecuteNonQuery();
                        Console.WriteLine("TestSnapshotUpdate table created.");
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("CREATE TABLE failed: {0}", ex.Message);
                    }
                    // Insert some data,在表中创建数据。
                    command1.CommandText =
                        "INSERT INTO TestSnapshotUpdate VALUES (1,N'abcdefg');"
                        + "INSERT INTO TestSnapshotUpdate VALUES (2,N'hijklmn');"
                        + "INSERT INTO TestSnapshotUpdate VALUES (3,N'opqrstuv');";
                    try
                    {
                        command1.ExecuteNonQuery();
                        Console.WriteLine("Data inserted TestSnapshotUpdate table.");
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                    }
                    // Begin, but do not complete, a transaction 
                    // using the Snapshot isolation level.
                    /*开始但不完成一个在快照隔离级别上的事务,
                     */
                    SqlTransaction transaction1 = null;
                    try
                    {
                        transaction1 = connection1.BeginTransaction(IsolationLevel.Snapshot);
                        command1.CommandText =
                            "SELECT * FROM TestSnapshotUpdate WHERE ID BETWEEN 1 AND 3";
                        command1.Transaction = transaction1;
                        command1.ExecuteNonQuery();
                        Console.WriteLine("Snapshot transaction1 started.");
                        // Open a second Connection/Transaction to update data
                        // using ReadCommitted. This transaction should succeed.
                        /*打开第二个数据库连接,并创建一个在ReadCommitted上更新数据的事务。
                         * 这个事务能够成功。 
                         */
                        using (SqlConnection connection2 = new SqlConnection(connectionString))
                        {
                            connection2.Open();
                            SqlCommand command2 = connection2.CreateCommand();
                            command2.CommandText = "UPDATE TestSnapshotUpdate SET CharCol="
                                + "N'New value from Connection2' WHERE ID=1";
                            SqlTransaction transaction2 =
                                connection2.BeginTransaction(IsolationLevel.ReadCommitted);
                            command2.Transaction = transaction2;
                            try
                            {
                                command2.ExecuteNonQuery();
                                transaction2.Commit();//提交事务2
                                Console.WriteLine(
                                    "transaction2 has modified data and committed.");
                            }
                            catch (SqlException ex)
                            {
                                Console.WriteLine(ex.Message);
                                transaction2.Rollback();
                            }
                            finally
                            {
                                transaction2.Dispose();
                            }
                        }
                        // Now try to update a row in Connection1/Transaction1.
                        // This transaction should fail because Transaction2
                        // succeeded in modifying the data.
                        /*试图更新连接1和事务1中的一行数据。这个事务执行失败,
                         * 这是因为在事务2中已经成功修改了数据。
                         * 事务1将自动回滚。
                         */
                        command1.CommandText =
                            "UPDATE TestSnapshotUpdate SET CharCol="
                            + "N'New value from Connection1' WHERE ID=1";
                        command1.Transaction = transaction1;
                        command1.ExecuteNonQuery();
                        transaction1.Commit();
                        Console.WriteLine("You should never see this.");//正常执行情况下应该不会再控制台中输出此句。
                    }
                    catch (SqlException ex)
                    {
                        Console.WriteLine("Expected failure for transaction1:");
                        Console.WriteLine("  {0}: {1}", ex.Number, ex.Message);
                    }
                    finally
                    {
                        transaction1.Dispose();
                    }
                }
                // CLEANUP:清理程序
                // Turn off Snapshot isolation and delete the table
                using (SqlConnection connection3 = new SqlConnection(connectionString))
                {
                    connection3.Open();
                    SqlCommand command3 = connection3.CreateCommand();
                    command3.CommandText =
                        "ALTER DATABASE AdventureWorks SET ALLOW_SNAPSHOT_ISOLATION OFF";
                    try
                    {
                        command3.ExecuteNonQuery();
                        Console.WriteLine(
                            "CLEANUP: Snapshot isolation turned off in AdventureWorks.");
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("CLEANUP FAILED: {0}", ex.Message);
                    }
                    command3.CommandText = "DROP TABLE TestSnapshotUpdate";
                    try
                    {
                        command3.ExecuteNonQuery();
                        Console.WriteLine("CLEANUP: TestSnapshotUpdate table deleted.");
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("CLEANUP FAILED: {0}", ex.Message);
                    }
                }
            }
        }
    }
    作者:xwdreamer
    欢迎任何形式的转载,但请务必注明出处。
    分享到:
  • 相关阅读:
    C#中IDisposable学习
    C# volatile与lock
    TFS源代码管理
    C#如何获取真实IP地址
    c# 协变和逆变
    基本数据类型
    用户交互
    变量.常量
    输出语句,注释,
    基础知识随笔
  • 原文地址:https://www.cnblogs.com/xwdreamer/p/2297079.html
Copyright © 2011-2022 走看看