博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SQL Server之事务基础知识
阅读量:6947 次
发布时间:2019-06-27

本文共 2834 字,大约阅读时间需要 9 分钟。

事务是对数据库执行的一个操作单位。

事务的本质特征:
所有的事务都有开始和结束;
事务可以被保存或撤销;
如果事务在中途失败,事务中的任何部分都不会被记录到数据库

控制事务

当一个事务被执行并成功完成时,虽然从输出结果来看目标表已经被修改了,但实际上目标表并不是立即被修改。
当事务成功完成时,利用事务控制命令最终认可这个事务,可以把事务所做的修改保存到数据库,也可以撤销事
务所做的修改。
commit命令
commit命令用于把事务所做的修改保存到数据库,它把上一个commit或rollback命令之后的全部事务都保存到
数据库。在执行 commit transaction语句后不能回滚事务。
rollback命令
rollback命令用于撤销还没有保存到数据库的命令,它只能用于撤销上一个commit或rollback命令之后的事务
savepoint命令(在sql中为save tran或save transaction)
保存点是事务过程中的一个逻辑点,我们可以把事务回退到这个点,而不必回退整个事务。
语法:savepoint savepoint_name
这个命令就是事务语句之间创建一个保存点。rollback命令可以撤销一组事务操作,而保存点可以将大量事务操作
划分为较小的、更易于管理的组。 

begin transaction
insert into score values(
'
F002
'
,
'
M006
'
,
99
)
save tran sp1
insert into score values(
'
F009
'
,
'
M007
'
,
100
)
rollback tran sp1
commit                                      //结果数据库中添加了第一条语句,而第二条语句还未保存到数据库

rollback to savepoint命令(Oracle数据库、DB2数据库 )

语法:rollback to savepoint_name
release savepoint命令(Oracle数据库、DB2数据库
这个命令用于删除创建的保存点。在某个保存点被释放后,就不能在利用rollback命令来撤销这个保存点之后的事务
操作。利用这个命令可以避免意外地回退到某个不再需要的保存点。
语法:release savepoint savepoint_name
set transaction命令
这个命令用于初始化数据库事务,可以指定事务的特性。
我们知道在线程中常常会出现竞态或死锁的问题,其实在数据库中也会出现并发的问题。
那么如何解决数据库并发问题呢?
解决此问题的办法就是为数据库加锁,以防止多个组件读取数据,通过锁住事务所用的数据,能保证开锁之前,只有本事务才能
访问数据库。这样就避免了交叉存取的问题。
在sql server数据库中没有READ ONLY(只读锁)和READ WRITE(写入锁),但是在这里简单介绍一下。
只读锁是非独占的,多个并发的事务都能获得只读锁,只进行查询事务,很适合生成报告,而且能够提高事务完成的速度;
写入锁是独占的,任意时间只能有一个事务可以获得写入锁,可以对数据库进行查询和操作数据的事务。
如果事务是READ WRITE类型的,数据库必须对数据库对象进行加锁,从而在多个事务同时发生时保持数据完整性。
如果事务是READ ONLY类型的,数据库就不会建立锁定,这样就会提高事务的性能。
语法:

SET TRANSACTION
    {READ ONLY}
|{READ WRITE}
|
                
    {
     ISOLATION LEVEL
    【 READ COMMITTED
        
| READ UNCOMMITTED
        | REPEATABLE READ
        |
 SERIALIZABLE
    】
    }                       

四种事务的隔离级别

要理解这些隔离级别的差异,首先了解如下几个概念:脏读、不可重复读、幻影读取。
脏读:
假设同一个A和B两个同时并发操作数据库,A和B执行的任务如下:从数据库读取整数N,将N再加上10,将新的N更新回数据库。
这两个并发执行的实例可能发生下面的执行顺序。
1.A从数据库中读取整数N,当前数据库中N=0;
2.N加上10,并将其更新到数据库中,当前数据库中N=10,然而A的事务还没有提交,所以数据库更新还没有称之为持久性的。
3.B从数据库中读取整数N,当前数据库中N=0;
4.A回滚了事务,所以N恢复到了N=0;
5.B将N加上了10,并将其更新到数据库中,当前数据库中N=20。
这里出现了B在A提交前读取了A所更新的数据,由于A回滚了事务,所以数据库中出现了错误的数据20,尽管A回滚了事务,但是
A更新的数据还是间接的通过B被更新到了数据库中。这种读取了未提交的数据的方法就叫脏读问题。
不可重复读:
当一个用户从数据库中读取数据的时候,另外一个用户修改了这条数据,所以数据发送了改变,当再次读取的时候就出现了不可重
复读的问题。
幻影读取:
在两次数据库操作读取操作之间,一组新的数据会出现在数据库中,
1.A从数据库中检索到了一些数据;
2.B通过Insert插入一些新的数据;
3.A再次查询的时候,新的数据就会出现。
了解了这几个概念,下面来看一下四种事务的隔离级别的区别:
READ UNCOMMITTED
最低隔离级,允许脏读或 0 级隔离锁定,这表示不发出共享锁并忽略所以锁,也不接受排它锁。
READ COMMITTED
当数据正被读取时,可以控制共享锁。不允许脏读,但数据可在事务结束前更改,从而产生不可重复读取幻像数据。该选项是 SQL Server 的默认值。
REPEATABLE READ
锁定查询中使用的所有数据以防止其他用户更新、删除数据等,但是其他用户可以将新的幻像行插入数据集,且可以读取。因为并发低于默认隔离级别,所以应只在必要时才使用该选项。
SERIALIZABLE
事务的最高隔离级,锁定整个数据集,以防止其他用户在事务完成之前更新数据集或将行插入数据集内。因为并发级别较低,所以应只在必要时才使用该选项。该选项的作用与在事务内所有 SELECT 语句中的所有表上设置 HOLDLOCK 相同。
事务的一个例子:

SET TRANSACTION ISOLATION LEVEL   REPEATABLE READ
begin transaction
save tran sp1
insert into score values(
'
F002
'
,
'
M006
'
,
99
save tran sp2
insert into score values(
'
F009
'
,
'
M007
'
,
100
save tran sp3
delete from score 
where
 sid
>=
39
rollback tran sp2
commit

转载地址:http://pihnl.baihongyu.com/

你可能感兴趣的文章
JavaWeb部分面试题
查看>>
mac osx 系统开发php 的一些工具
查看>>
Tcp的三次握手,以及原理详解
查看>>
sprintboot 中占位符及多环境配置
查看>>
Oracle资源
查看>>
你需要一点点CIL
查看>>
Java中的位运算
查看>>
java连接mysql的一个小例子
查看>>
laravel queue 修改之后不生效的坑
查看>>
[USACO07JAN]Balanced Lineup
查看>>
[入门OJ3876]怎样学习哲学
查看>>
陶哲軒實分析 習題3.6.9
查看>>
Python国内豆瓣源
查看>>
html页面的局部刷新
查看>>
C#不常见的语法
查看>>
[摘录]高效人士七习惯—以终为始原则
查看>>
Office Visio简介
查看>>
[摘录]第4章 不道德的谈判策略
查看>>
mvc 截取上传图片做头像,自动生成不同小尺寸缩略图
查看>>
微信 登录 Scope 参数错误或没有 Scope 权限
查看>>