T-SQL:事务

为什么需要事务?

假定钱从A转到B,至少需要两步:
1.A的资金减少
2.然后B的资金相应增加

例子

先建立一个表,再增加一个约束,插入两条数据

create table bank
(
    cId char(4) primary key,
    balance money
)

alter table bank
add constraint CH_balance check(balance>=10)

go
insert into bank values('0001',1000)
insert into bank values('0002',10)
go

这里写图片描述



做好准备工作之后,执行下面两条语句,来完成转账

update bank set balance=balance-1000 where cid='0001'
update bank set balance=balance+1000 where cid='0002'

这里写图片描述
执行的时候会报一个错误,因为第一条语句执行完之后会为0,和约束冲突
,所以不会执行成功
又因为第一条的错误是运行时错误,所以仍然会接着执行下面的语句。
并且第二条语句不和约束冲突,所以会正常执行。
这里写图片描述
现在的情况是0001的钱没有扣除,而002的钱增加了,这样的情况在银行是绝对不让发生的。

解决办法:让这两句话作为一个整体来执行,要么都成功,要么都失败

事务的四个特征

原子性

原子性:一个事务对数据库的所有操作,要么全部执行,要么什么也不做。

隔离性

隔离性:多个事务并发执行时,保证执行结果是正确的。比如我在修改数据的时候,不允许别人读取。



可以做这样一个实验
我先在当前的SSMS执行

begin transaction
    delete from bank;

这里写图片描述
然后再开启一个SSMS执行

select * from bank

这里写图片描述
执行所花时间一直在增长,没有结果,也没有消息。此时这个进程在等待另一个进程操作完成。
一旦我在第一个SSMS执行

rollback

这里写图片描述
第二个SSMS会立刻执行,查询出结果。
第一个SSMS中的事务执行的时候锁住了这张表,第二个SSMS中的语句无法操作这张表,只能等待。
封锁对象的大小(一行数据或一张表或。。。)称为封锁的粒度。
封锁的粒度越大,并发度也就越小,系统的开销也就越小。

持久性

持久性:事务完成之后,它对于系统的影响是永久性的。该修改即使出现系统故障也将一直保持。

一致性

一致性:保证数据的完整性(说白了就是保证数据是正确的,啥是正确的,是由所建立的那些约束所限定的,符合这些约束的数据才是正确的,这些约束又是由现实世界中对象的特征来制定的)
数据的完整性是数据满足数据库描述对象的实际意义。
DBMS必须提供一种功能来保证数据库中的数据是正确的,避免非法的不符合语义的错误数据的输入与输出。检查数据库中的数据是否完整地条件称为“完整性检查”。数据库中数据应该满足的条件称为“完整性的约束条件”。
DBMS中执行完整性检查的子系统称为“完整性子系统”。其功能为:
1.监督事务的执行,并测试是否违反完整性规则
2.若有违反现象,则采取恰当的操作,譬如拒绝操作、报告违反情况、改正错误等方法来处理。

比如,现实世界中年龄不会小于0,于是定义了一个约束字段age要大于0。
这样数据库中的年龄应该都符合这个约束。



满足这四个特征的操作叫做事务。
事务指访问并可能更新数据库中各种数据项的一个程序执行单元(unit)–也就是由多个sql语句组成,必须作为一个整体执行
这些sql语句作为一个整体一起向系统提交,要么都执行、要么都不执行。

隐式事务,就是平时写的sql语句,每一条语句都是一个事务
显式事务,手动将多条语句打包成一个事务
在数据库中所有的执行单元都是事务
事务是最小的执行单元

事务语法

开启事务(begin transaction,可简写为begin tran)
一般定义一个局部变量记录信息
书写T-SQL语句执行代码,并记录数据
判断记录的信息是否满足要求
满足提交事务(commit transaction,可简写为commit)
不满足回滚(rollback transaction,可简写为rollback)



开启事务,begin tran,从这句话开始,其后所有的代码都是这个事务中的操作,直到出现提交或回滚操作。
提交事务,commit,就是告诉数据库从begin tran开始执行的代码全部生效。
回滚,rollback,就是告诉数据库刚才的代码不算,操作回到执行之前的状态。

使用事务

先将数据恢复到原来的
这里写图片描述
然后执行

begin tran
    begin try
        update bank set balance=balance-1000 where cid='0001';
        update bank set balance=balance+1000 where cid='0002';
        commit;
    end try
    begin catch
        rollback;
    end catch

显示结果为
这里写图片描述
查看表中的数据
这里写图片描述
问题解决了,但是怎么在c#中知道是否执行成功,怎么用c#操作呢?可以把这些sql语句都写在c#里,但那样代码量太了,可以用存储过程,在下一篇博客里。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 15
    评论
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值