在数据库系统上执行并发操作时事务是作为最小

作者: www.9159.com  发布:2019-11-06

3、MySQL事务隔离级别

事务隔离级别 脏读 不可重复读 幻读
读未提交(read-uncommitted)
不可重复读(read-committed)
可重复读(repeatable-read)
串行化(serializable)

 

protected void Button1_Click(object sender, EventArgs e)
        {
            SqlConnection con = new SqlConnection(@"Data Source=.;database=oa2010;uid=sa;pwd=sa");
            con.Open();
            SqlTransaction tran = con.BeginTransaction();//先实例SqlTransaction类,使用这个事务使用的是con 这个连接,使用BeginTransaction这个方法来开始执行这个事务
            SqlCommand cmd = new SqlCommand();
            cmd.Connection = con;
            cmd.Transaction = tran;
            try
            {
                //在try{} 块里执行sqlcommand命令,
                cmd.CommandText = "update a set money=money-" + Convert.ToInt32(TextBox1.Text) + " where id=13";//张三id
                cmd.ExecuteNonQuery();
                cmd.CommandText = "update a set money=money+"+ Convert.ToInt32(TextBox1.Text) +" where id=14";//李四id
                cmd.ExecuteNonQuery();
                tran.Commit();//如果两个sql命令都执行成功,则执行commit这个方法,执行这些操作
                Label1.Text = "添加成功";
            }
            catch
            {
                Label1.Text = "添加失败";
                tran.Rollback();//如何执行不成功,发生异常,则执行rollback方法,回滚到事务操作开始之前;
            }
        }

 

持久性:事务完成之后,它对数据库系统的影响是持久的,即使是系统错误,重新启动系统后,该事务的结果依然存在。

4.2隐式事务

开启关闭隐式事务的方法:

SET IMPLICIT_TRANSACTIONS ON/OFF;

set implicit_transactions on;
insert into dept values(101,'erer','男',9)
rollbac

C# 代码调用存储过程

   2)一致性: Consistency: 当事务完成时,数据必须处于一致状态。

     2、游标的基本操作

SQL Server 表的管理_关于事务操作的详解(案例代码)

 

     begin

     游标可以对一个select的结果集进行处理,或是不需要全部处理,就会返回一个对记录集进行处理之后的结果。

2、事务的acid属性:

  • 原子性:事务处理语句是一个整体,不可分割。Atomicity--A

  • 一致性:事务处理前后数据库前后状态要一致。Consistency--C

  • 分割性(隔离性):多个事务并发处理互不干扰。Isolation--I

  • 持久性:事务处理完成后,数据库的变化将不会再改变。Durability--D

注意:在 MySQL 命令行的默认设置下,事务都是自动提交的,即执行 SQL 语句后就会马上执行 COMMIT 操作。因此要显式地开启一个事务务须使用命令 BEGIN 或 START TRANSACTION,或者执行命令 SET AUTOCOMMIT=0,用来禁止使用当前会话的自动提交。

protected void btnzz_Click(object sender, EventArgs e)
        {
            SqlConnection conn = new SqlConnection(@"Data Source=.;database=oa2010;uid=sa;pwd=sa");
            SqlCommand cmd = new SqlCommand("proc_zhuanzhang",conn);
            cmd.CommandType = CommandType.StoredProcedure;
            conn.Open();
            SqlParameter prar = new SqlParameter();//传递参数
            cmd.Parameters.AddWithValue("@toNameID", 13);//张三
            cmd.Parameters.AddWithValue("@fromNameID", 14);//李四
            cmd.Parameters.AddWithValue("@momeys", Convert.ToInt32(TextBox1.Text));
            cmd.Parameters.Add("@return", "").Direction = ParameterDirection.ReturnValue;//获取存储过程的返回值
            cmd.ExecuteNonQuery();

            string value = cmd.Parameters["@return"].Value.ToString();//把返回值赋值给value
            if (value == "0")
            {

                Label1.Text = "转账成功";

            }

            else
            {
                Label1.Text = "转账失败";

            }

        }

 

   ----- 执行语句1

     D、 关闭游标

 4、SQL的事务模式

事务分类:

  1. 显式事务:用begin transaction明确指定事务的开始。
  2. 隐性事务:打开隐性事务:set implicit_transactions on,当以隐性事务模式操作时,SQL Servler将在提交或回滚事务后自动启动新事务。无法描述事务的开始,只需要提交或回滚事务。
  3. 自动提交事务:SQL Server的默认模式,它将每条单独的T-SQL语句视为一个事务。如果成功执行,则自动提交,否则回滚。
create proc proc_zhuanzhang
@toNameID int,--接收转账的账户
@fromNameID int,--转出自己的账户
@momeys int --转账的金额
as
begin tran tran_money   --开始事务
declare @tran_error int;
set @tran_error = 0;
    begin try
        update a set [money] = [money]-@momeys where id = @fromNameID;
        set @tran_error = @tran_error+@@ERROR;
        --测试出错代码,看看张三的钱减少,李四的钱是否会增加
        --set @tran_error = 1;

        update a set [money] = [money]+@momeys where id = @toNameID;
        set @tran_error = @tran_error+@@ERROR;
    end try

begin catch
    PRINT '出现异常,错误编号:' + convert(varchar,error_number()) + ',错误消息:' + error_message()
    SET @tran_error = @tran_error + 1
end catch

IF(@tran_error > 0)
    BEGIN
        --执行出错,回滚事务
        ROLLBACK TRAN;
        PRINT '转账失败,取消交易!';
    END
ELSE
    BEGIN
        --没有异常,提交事务
        COMMIT TRAN;
        PRINT '转账成功!';
    END

     begin

                如果n为正整数,则读取上次读取记录之后第n条记录

 4.1显示事务

 T-SQL中管理事务的语句:
  1 开始事务: begin transaction
  2 提交事务:commit transaction
  3 回滚事务: rollback transaction

 案例代码:

begin transaction
insert into dept  values(100,'陈浩','男',19)
save transaction sp1;
insert into dept  values(101,'erer','男',9)
rollback transaction sp1;
commit transaction;
--执行过程中插入第二条语句后,事务回滚到第二条数据之前,也就是第二条动作被撤销后,
--最后提交事务后,表中只有一条数据。

代码附上:事务两种方法下载

   if  @error <> 0  --有误

        c、 rollback transaction语句

1、概念

事务(transaction):

  是将多个修改语句组合在一起的方法,这个方法中的所有语句只有全部执行才能正确完成功能。即要么全部执行,要么全部不执行。

第一种:存储过程

   4)持久性: 不管系统是否发生了故障,事务处理的结果都是永久性的。

     scroll_locks:游标锁定,游标在读取时,数据库会将该记录锁定,以便游标完成对记录的操作

一、事务概念
    事务是一种机制、是一种操作序列,它包含了一组数据库操作命令,这组命令要么全部执行,要么全部不执行。因此事务是一个不可分割的工作逻辑单元。在数据库系统上执行并发操作时事务是作为最小的控制单元来使用的。这特别适用于多用户同时操作的数据通信系统。例如:订票、银行、保险公司以及证券交易系统等。
二、事务属性
事务4大属性:
1   原子性(Atomicity):事务是一个完整的操作。
2   一致性(Consistency):当事务完成时,数据必须处于一致状态。
3   隔离性(Isolation):对数据进行修改的所有并发事务是彼此隔离的。
4   持久性(Durability):事务完成后,它对于系统的影响是永久性的。
三、创建事务
T-SQL中管理事务的语句:
1 开始事务: begin transaction
2 提交事务:commit transaction
3 回滚事务: rollback transaction
事务分类:
1 显式事务:用begin transaction明确指定事务的开始。
2 隐性事务:打开隐性事务:set implicit_transactions on,当以隐性事务模式操作时,SQL Servler将在提交或回滚事务后自动启动新事务。无法描述事务的开始,只需要提交或回滚事务。
3 自动提交事务:SQL Server的默认模式,它将每条单独的T-SQL语句视为一个事务。如果成功执行,则自动提交,否则回滚。

    3) 自动提交事务: 这是SQL Server的默认模式,它将每条单独的T-SQL语句视为一个事务。如果成功执行,则自动提交。如果错误,则自动回滚。

          游标的基本操作有定义游标、打开游标、循环读取游标、关闭游标、删除游标。

 

   --判断

        a、 显示事务

下面的两种事务方法,附上代码

  1. 示例

             fetch absolute n; 读取某一行

 

 

原子性:事务内的所有工作要么全部完成,要么全部不完成,不存在只有一部分完成的情况。

二、第二种方法:ADO.net

 SQL 事务:

          deallocate cursor_name;

    3)  回滚事务: rollback transaction

     3、游标操作示例

   else  

          # 支持对结果集中当前位置的进行修改

 

             fetch prior; 读取上一行

   3)隔离性: Lsolation: 对数据进行修改的所有并发事务是彼此隔离的,它不以任何方式依赖或影响其他事务。

     由于游标是将记录集进行一条条的操作,所以这样给服务器增加负担,一般在操作复杂的结果集的情况下,才使用游标。SQL Server 2005有三种游标:T-SQL游标、API游标、客户端游标。

  1. 事务分类
--创建临时用表

if (object_id('temp_tab', 'u') is not null)

    drop table temp_tab

go

create table temp_tab(

    id int primary key identity(100000, 1),

    name varchar(200)

)

go

 

begin try

    begin tran;

    --没有createTime字段

    alter table temp_tab drop column createTime;

    commit tran;

end try

begin catch

    exec proc_error_info;--显示异常信息

    if (xact_state() = -1)

    begin

        print '会话具有活动事务,但出现了致使事务被归类为无法提交的事务的错误。'

            + '会话无法提交事务或回滚到保存点;它只能请求完全回滚事务。'

            + '会话在回滚事务之前无法执行任何写操作。会话在回滚事务之前只能执行读操作。'

            + '事务回滚之后,会话便可执行读写操作并可开始新的事务。';

    end

    else if (xact_state() = 0)

    begin

        print '会话没有活动事务。';

    end

    else if (xact_state() = 1)

    begin

        print '会话具有活动事务。会话可以执行任何操作,包括写入数据和提交事务。';

    end

end catch

go

           commit transaction

     在程序中,有时候完成一些Transact-SQL会出现错误、异常信息。如果我们想自己处理这些异常信息的话,需要手动捕捉这些信息。那么我们可以利用try catch完成。

   ------

                如果n为,则读取上次读取的记录

    1)开始事务:  begin  transaction

     如果 TRY 块中没有错误,控制将传递到关联的 END CATCH 语句后紧跟的语句。如果 END CATCH 语句是存储过程或触发器中的最后一条语句,控制将传递到调用该存储过程或触发器的语句。

           rollback  transaction

TRY...CATCH 使用错误函数来捕获错误信息。

    ERROR_NUMBER() 返回错误号。

    ERROR_MESSAGE() 返回错误消息的完整文本。此文本包括为任何可替换参数(如长度、对象名称或时间)提供的值。

    ERROR_SEVERITY() 返回错误严重性。

    ERROR_STATE() 返回错误状态号。

    ERROR_LINE() 返回导致错误的例程中的行号。

    ERROR_PROCEDURE() 返回出现错误的存储过程或触发器的名称。

    set  @error = @error + @@error  --累积错误

             fetch last; 读取最后一行

   XXXXXX  业务逻辑

        使用时,需要设置set implicit_transaction on语句,将隐式事务模式打开,下一个语句会启动一个新的事物,再下一个语句又将启动一个新事务。

 

     1、游标实际上是一种能从多条数据记录的结果集中每次提取一条记录的机制。游标可以完成:

  1.  定义: 

     forward only | scroll:前一个参数,游标只能向后移动;后一个参数,游标可以随意移动

  1. 事务必须具备的特性: 

          # 允许定位到结果集中的特定行

    set  @error = @error + @@error  --累积错误

--创建一个游标

declare cursor_stu cursor scroll for

    select id, name, age from student;

--打开游标

open cursor_stu;

--存储读取的值

declare @id int,

        @name nvarchar(20),

        @age varchar(20);

--读取第一条记录

fetch first from cursor_stu into @id, @name, @age;

--循环读取游标记录

print '读取的数据如下:';

--全局变量

while (@@fetch_status = 0)

begin

    print '编号:' + convert(char(5), @id) + ', 名称:' + @name + ', 类型:' + @age;

    --继续读取下一条记录

    fetch next from cursor_stu into @id, @name, @age;

end

--关闭游标

close area_cursor;

 

--删除游标

--deallocate area_cursor;

   set @error = 0

在数据库中有时候需要把多个步骤的指令当作一个整体来运行,这个整体要么全部成功,要么全部失败,这就需要用到事务。

    

    2、 事务的模式

   1) 原子性:  Atomicity  :事务是一个完整的操作, 个元素是不可再分的。事务中所以元素必须作为一个整体提交或回滚。如果十五中任何元素失败,则整个事务将失败。

             fetch pelative n

  

          检索方式如下:

    2)  提交事务: commit transaction

        c、 隐式事务

  1. 如何执行事务:
--

--简单try catch示例,无法处理错误

begin try

    select * * from student;

end try

begin catch

    exec proc_error_info;

end catch

go

--

--简单try catch示例,不处理错误(不存在的表对象)

begin try

    select * from st;

end try

begin catch

    exec proc_error_info;

end catch

go

--

--异常处理,能处理存储过程(触发器)中(不存在表对象)的错误信息

if (object_id('proc_select') is not null)

    drop procedure proc_select

go

create proc proc_select

as

    select * from st;

go

begin try

    exec proc_select;

end try

begin catch    

    exec proc_error_info;

end catch

go

 

Ø 异常

   

隔离性:事务直接是相互隔离的,如果有两个事务对同一个数据库进行操作,比如读取表数据。任何一个事务看到的所有内容要么是其他事务完成之前的状态,要么是其他事务完成之后的状态。一个事务不可能遇到另一个事务的中间状态。

 

    4、 事务的示例

   ---- 执行语句2

        隐式事务是指当事务提交或回滚后,SQL Server自动开始事务。因此,隐式事务不需要使用begin transaction显示开始,只需直接失业提交事务或回滚事务的T-SQL语句即可。

    1) 显示事务: 用begin transaction 明确指定事务的开始

    # 示例:用异常处理错误信息

    print  '提交事务'

     # 错误函数

  begin transaction  --开始事务

                如果n为负数,则倒数提取第n条记录

 

TRY…CATCH 构造包括两部分:一个 TRY 块和一个 CATCH 块。如果在 TRY 块中所包含的 Transact-SQL 语句中检测到错误条件,控制将被传递到 CATCH 块(可在此块中处理该错误)。

   declare @error  int  --定义变量,累积事务执行过程中的错误

示例

    2) 隐式事务: 通过设置 set implicit_transactions on 语句,将隐式事务模式设置为打开。当以隐式事务模式操作时,SQlServer将在提交或回滚事务后自动启动新事务。不需要描述每个事务的开始,只要提交或回滚每个事务即可。

        事务有若干条T-SQL指令组成,并且所有的指令昨晚一个整体提交给数据库系统,执行时,这组指令要么全部执行完成,要么全部取消。因此,事务是一个不可分割的逻辑单元。

     end

             fetch next; 读取下一行

事务是作为单个逻辑单元执行的一系列操作。 多个操作作为一个整体向系统提交,要么执行、要么都不执行,事务是一个不可分割的工作逻辑单元。这特别适用于多用户同时操作的数据通信系统。例如:订票、银行、保险公司以及证券交易系统等。

     C、 检索游标

   

             fetch first; 读取第一行

    print  '回滚事务'

--错误消息存储过程

if (object_id('proc_error_info') is not null)

    drop procedure proc_error_info

go

create proc proc_error_info

as

    select 

        error_number() '错误编号',

        error_message() '错误消息',

        error_severity() '严重性',

        error_state() '状态好',

        error_line() '错误行号',

        error_procedure() '错误对象(存储过程或触发器)名称';

go

     end

     A、 定义游标

          # 从结果集的当前位置检索一行或多行数据

        b、 自动提交事务

        显示事务就是用户使用T-SQL明确的定义事务的开始(begin transaction)和提交(commit transaction)或回滚事务(rollback transaction)

     read_only:只读游标

Ø 事务

     B、 打开游标

        开始事务,而@@trancount全局变量用来记录事务的数目值加1,可以用@@error全局变量记录执行过程中的错误信息,如果没有错误可以直接提交事务,有错误可以回滚。

Ø 游标

# 示例:处理异常日志信息

     # 示例:无法提交的事务

        b、 commit transaction语句

        常用T-SQL事务语句:

                如果n为,则不读取任何记录

        事务有4个属性:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)以及持久性(Durability),也称作事务的ACID属性。

    3、 事务处理

                如果n为负数,则读取上次读取记录之前第n条记录

        可以设置事务进入隐式方式:set implicit_transaction on;

          open cursor_name;

     optimistic:该参数不会锁定游标;此时,如果记录被读入游标后,对游标进行更新或删除不会超过

参数:

     TRY 块以 BEGIN TRY 语句开头,以 END TRY 语句结尾。在 BEGIN TRY 和 END TRY 语句之间可以指定一个或多个 Transact-SQL 语句。CATCH 块必须紧跟 TRY 块。CATCH 块以 BEGIN CATCH 语句开头,以 END CATCH 语句结尾。在 Transact-SQL 中,每个 TRY 块仅与一个 CATCH 块相关联。

    1、 事务的特点

     E、 删除游标

          fetch cursor_name;

--

---异常、错误信息表

if (object_id('errorLog', 'U') is not null)

    drop table errorLog

go

create table errorLog(

    errorLogID int primary key identity(100, 1),    --ErrorLog 行的主键。

    errorTime datetime default getDate(),            --发生错误的日期和时间。

    userName sysname default current_user,            --执行发生错误的批处理的用户。

    errorNumber int,                                --发生的错误的错误号。

    errorSeverity int,                                --发生的错误的严重性。

    errorState int,                                    --发生的错误的状态号。

    errorProcedure nvarchar(126),                    --发生错误的存储过程或触发器的名称。

    errorLine int,                                    --发生错误的行号。

    errorMessage nvarchar(4000)

)

go

--

--存储过程:添加异常日志信息

if (object_id('proc_add_exception_log', 'p') is not null)

    drop proc proc_add_exception_log

go

create proc proc_add_exception_log(@logId int = 0 output)

as

begin

    set nocount on;

    set @logId = 0;

    begin try

        if (error_number() is null)

            return;



        if (xact_state() = -1)

        begin

            print '会话具有活动事务,但出现了致使事务被归类为无法提交的事务的错误。'

                + '会话无法提交事务或回滚到保存点;它只能请求完全回滚事务。'

                + '会话在回滚事务之前无法执行任何写操作。会话在回滚事务之前只能执行读操作。'

                + '事务回滚之后,会话便可执行读写操作并可开始新的事务。';

        end

        else if (xact_state() = 0)

        begin

            print '会话没有活动事务。';

        end

        else if (xact_state() = 1)

        begin

            print '会话具有活动事务。会话可以执行任何操作,包括写入数据和提交事务。';

        end



        --添加日志信息

        insert into errorLog values(getDate(), 

            current_user, error_number(), 

            error_severity(), error_state(), 

            error_procedure(), 

            error_line(), error_message());

        --设置自增值

        select @logId = @@identity;

    end try

    begin catch

        print '添加异常日志信息出现错误';

        exec proc_error_info;--显示错误信息

        return -1;

    end catch

end

go

--

---处理异常信息示例

declare @id int;

begin try

    begin tran;

    --删除带有外键的记录信息

    delete classes where id = 1;

    commit tran;

end try

begin catch

    exec proc_error_info;--显示错误信息

    if (xact_state() <> 0)

    begin

        rollback tran;

    end

    exec proc_add_exception_log @id output

end catch

select * from errorLog where errorLogID = @id;

go
--开始事务

begin transaction tran_bank;

declare @tran_error int;

    set @tran_error = 0;

    begin try

        update bank set totalMoney = totalMoney - 10000 where userName = 'jack';        

        set @tran_error = @tran_error + @@error;

        update bank set totalMoney = totalMoney + 10000 where userName = 'jason';

        set @tran_error = @tran_error + @@error;

    end try

    begin catch        

        print '出现异常,错误编号:' + convert(varchar, error_number()) + ', 错误消息:' + error_message(); 

        set @tran_error = @tran_error + 1;

    end catch

if (@tran_error > 0)

    begin

        --执行出错,回滚事务

        rollback tran;

        print '转账失败,取消交易';

    end

else

    begin

        --没有异常,提交事务

        commit tran;

        print '转账成功';

    end

go
declare cursor_name    --游标名称

cursor [local | global]    --全局、局部

[forward only | scroll]    --游标滚动方式

[read_only | scroll_locks | optimistic]    --读取方式

for select_statements                    --查询语句

[for update | of column_name ...]        --修改字段

        回滚事务,执行rollback tran语句后,数据会回滚到begin tran的时候的状态

          close cursor_name;

          游标打开后,可以使用全局变量@@cursor_rows显示读取记录条数

        自动提交事务是一种能够自动执行并能自动回滚事务,这种方式是T-SQL的默认事务方式。例如在删除一个表记录的时候,如果这条记录有主外键关系的时候,删除就会受主外键约束的影响,那么这个删除就会取消。

--简单try catch示例

begin try

    select 1 / 0;

end try

begin catch

    exec proc_error_info; --调用错误消息存储过程

end catch

go

# 示例:异常能处理的错误信息

异常不能处理编译期的错误,如语法错误。以及重编译造成部分名称对象得不到正确解析的时候所出现的错误。

        a、 begin transaction语句

     CATCH 块处理该异常错误后,控制将被传递到 END CATCH 语句后面的第一个 Transact-SQL 语句。如果 END CATCH 语句是存储过程或触发器中的最后一条语句,控制将返回到调用该存储过程或触发器的代码。将不执行 TRY 块中生成错误的语句后面的 Transact-SQL 语句。

        回滚事务,表示一个隐式或显示的事务的结束,对数据库所做的修改正式生效。并将@@trancount的值减1;

一致性:事务内的然后操作都不能违反数据库的然后约束或规则,事务完成时有内部数据结构都必须是正确的。

建议先阅读存储过程:SQL Server 存储过程

                如果n为正整数,则读取第n条记录

本文由9159.com发布于www.9159.com,转载请注明出处:在数据库系统上执行并发操作时事务是作为最小

关键词: