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

本文共 2905 字,大约阅读时间需要 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

转载于:https://www.cnblogs.com/jiajiayuan/archive/2011/07/13/2105398.html

你可能感兴趣的文章
福建省促进大数据发展:变分散式管理为统筹集中式管理
查看>>
开发环境、生产环境、测试环境的基本理解和区别
查看>>
tomcat多应用之间如何共享jar
查看>>
Flex前后台交互,service层调用后台服务的简单封装
查看>>
技术汇之物联网设备网关技术架构设计
查看>>
OSX10.11 CocoaPods 升级总结
查看>>
深入浅出Netty
查看>>
3.使用maven创建java web项目
查看>>
笔记本搜索不到某一AP广播的SSID,信道的原因
查看>>
基于Spring MVC的异常处理及日志管理
查看>>
MediaBrowserService 音乐播放项目《IT蓝豹》
查看>>
MySQL入门12-数据类型
查看>>
Windows Azure 保留已存在的虚拟网络外网IP(云服务)
查看>>
修改字符集
查看>>
HackTheGame 攻略 - 第四关
查看>>
js删除数组元素
查看>>
带空格文件名的处理(find xargs grep ..etc)
查看>>
华为Access、Hybrid和Trunk的区别和设置
查看>>
centos使用docker下安装mysql并配置、nginx
查看>>
关于HTML5的理解
查看>>