事务是什么?
是数据库操作的最小工作单元,这些操作作为一个整体一起向系统提交,要么都执行、要么都不执行;事务是一组不可再分割的操作集合(工作逻辑单元);
事务的特性
(1)A(原子性):事务是一个工作单元,各个元素是不可分的。要么全部成功,要么全部失败。
(2)C(一致性):事务是一个工作单元, 执行完成后,数据是正确的
(3)I(隔离性): 多个事务之间彼此隔离。
(4)D(持久性): 事务提交之后,对数据库的更改是永久保存的,就算是系统出现故障,也会保留。
事务创建
--开启事务 begin try begin tran --set implicit_transactions on --开启一个隐式事务 --在这里做t-sql commit tran --提交事务 end try begin catch rollback tran --撤回事务 end catch --set implicit_transactions off --关闭隐式事务
事务并发问题
(1)脏读(Dirty Read):一个事务读取另外一个事务还没有提交的数据叫脏读(事务T1修改了一行数据,但是还没有提交,这时候事务T2也读取了这条数据,当T2要对这个数据进行增加或修改操作并提交的时候,T1事务回滚了,这个时候T2原先读取的数据和数据库现在的数据是不一样的,那么事务T2读取的数据就是脏的。)。
(2)不可重复读(Unrepeatable Read):如果一个用户在一个事务中多次读取一条数据,而另外一个用户则同时更新啦这条数据,造成第一个用户多次读取数据不一致。 (其他解释:不可重复读是指在同一个事务内,两个相同的查询返回了不同的结果。比如:事务T1读取某一数据,事务T2读取并修改了该数据,T1再次读取该数据,便得到了不同的结果。)
(3)幻读(Phantom Read):是指同一个事务内多次查询返回的“数据条数”不一样(比如增加了或者减少了行记录)。比如同一个事务A内第一次查询时候有n条记录,但是第二次同等条件下查询却又n+1条 记录,这就好像产生了幻觉,为啥两次结果不一样那。其实和不可重复读一样,发生幻读的原因也是另外一个事务新增或者删除或者修改了第一个事务结果集里面的数据。不同在于不可重复读是同一个记录的数据内容被修改了,幻读是数据行记录变多了或者少了。
(4)丢失或者覆盖更新
事务a和b都对这个数据进行修改,可能a先修改,紧接着b又修改,造成了事务a的数据被覆盖了,一个事务在不知道其他事务存在的情况下对数据进行修改,造成的数据丢失。
总结:
脏读是指一个事务读取到了其他事务没有提交的数据,不可重复读是指一个事务内多次根据同一个查询条件查询出来的“同一行记录的值不一样”,幻读是指一个事务内多次 根据同个条件查出来的记录行数不一样。为了解决事务并发带来的问题,才有了事务规范中的四个事务隔离级别,不同隔离级别对上面问题部分或者全部做了避免。
隔离级别
解决事务并发问题,可以设置事务隔离级别,隔离级别越低,并发问题越严重。
(1)read uncommited(未提交读)
相当于没有设置级别,都会产生。
(2)read commited(已提交读)
这是数据库默认的隔离级别,可以解决脏读,但是会产生不可重复和幻读。这个隔离级别规定只能读取那些没有被其它事务占用读取的数据,所以能够解决因事务回滚导致产生的脏读(with(nolock)能破坏这个隔离级别)
(3)reapeatable read (可以重复读),相当于(HOLDLOCK)
可以有效的避免脏读,不可重复读,但是会产生幻读。
(4)serializebal(可序列化)
能够解决脏读,不可重复读, 幻读。
示例:
--开启事务 begin try --设置隔离级别 可重复读 set tran isolation level repeatable read begin tran --set implicit_transactions on --开启一个隐式事务 --在这里做t-sql commit tran --提交事务 end try begin catch rollback tran --撤回事务 end catch --set implicit_transactions off --关闭隐式事务
as