子夜双鱼

每天进步一点点!——选择、专注、榜样

  博客园  ::  :: 新随笔  ::  :: 订阅 订阅  :: 管理

引子

begin tran

    do something...

commit tran;

 

今天用了这个语句,发现东西久久木有执行。不禁想问,SQL中的事务是什么?怎么使用?在什么场合下使用?

 

SQL中的事务是什么?怎么使用? 

度之得:http://www.cnblogs.com/lf78995525/archive/2010/07/21/1781983.html

一、事务概念

事务是一种机制、是一种操作序列,它包含了一组数据库操作命令,这组命令要么全部执行,要么全部不执行。因此事务是一个不可分割的工作逻辑单元。在数据库系统上执行并发操作时事务是作为最小的控制单元来使用的。这特别适用于多用户同时操作的数据通信系统。例如:订票、银行、保险公司以及证券交易系统等。

 

二、事务属性

事务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语句视为一个事务。如果成功执行,则自动提交,否则回滚。

 

示例:张三转800元到李四帐户上。

use stuDB
go
--创建帐户表bank--
if exists(select* from sysobjects where name='bank')
    drop table bank
create table bank
(
    customerName char(10),    --顾客姓名
    currentMoney money        --当前余额
)
go
/**//*--添加约束,帐户不能少于元--*/
alter table bank add
        constraint CK_currentMoney check(currentMoney>=1)
/**//*--插入测试数据--*/
insert into bank(customerName,currentMoney)
select '张三',1000 union
select '李四',1

select * from bank
go

/**//*--使用事务--*/
use stuDB
go
--恢复原来的数据
--update bank set currentMoney=currentMoney-1000 where customerName='李'
set nocount on    --不显示受影响的行数
print '查看转帐事务前的余额'
select * from bank
go

/**//*--开始事务--*/
begin transaction
declare @errorSum int    --定义变量,用于累计事务执行过程中的错误
set @errorSum =0 --此句原文漏掉咯。必须给@errorSum 赋初值,否则if(@errorSum >0)始终返回true.
/**//*--转帐--*/
update bank set currentMoney=currentMoney-800 where customerName='张三'
set @errorSum=@errorSum+@@error    --累计是否有错误
update bank set currentMoney=currentMoney+800 where customerName='李四'
set @errorSum=@errorSum+@@error --累计是否有错误

print '查看转帐事务过程中的余额'
select * from bank

/**//*--根据是否有错误,确定事务是提交还是回滚--*/
if @errorSum>0
    begin
        print '交易失败,回滚事务.'
        rollback transaction
    end
else
    begin
        print '交易成功,提交事务,写入硬盘,永久保存!'
        commit transaction
    end
go

print '查看转帐后的余额'
select * from bank
go

 

 

在什么场合下使用? (复杂存储过程呢?)

再度之得:http://www.cnblogs.com/Garden-blog/archive/2011/04/20/2022307.html

不能用于事务的操作:

创建数据库 create database

修改数据库 alter database

删除数据库 drop database

恢复数据库 restore database

加载数据库 load database

备份日志文件 backup log

恢复日志文件 restore log

更新统计数据 update statitics

授权操作              grant

复制事务日志 dump tran

磁盘初始化           disk init

更新使用sp_configure后的系统配置           reconfigure

 

  顺便扩展下自己

源于:http://www.cnblogs.com/Garden-blog/archive/2011/04/20/2022307.html

1.存储过程的优势

(1) 能实现模块化程序设计。存储过程是根据实际功能的需要创建的一个程序模块,并被存储在数据库中。以后用户要完成该功能,只要在程序中直接调用该存储过程即可,而无需再编写重复的程序代码。存储过程可由数据库编程方面的专门人员创建,并可独立于程序源代码而进行修改和扩展。

(2) 使用存储过程可以提高执行效率。当客户程序需要访问服务器上的数据时,一般要经过5个步骤:

 ● 查询语句被发送到服务器;

 ● 服务器编译T-SQL语句;

 ● 优化产生查询执行计划;

 ● 数据库引擎执行查询;

 ● 执行结果发回客户程序。

如果执行存储在客户端本地的T-SQL程序,那么每次执行该程序时,对于程序中的每一条语句都要经过以上5个步骤。而存储过程在创建时就被编译和优化,当存储过程第一次被执行时,SQL Server为其产生查询计划并将其保存在内存中,这样以后在调用该存储过程时就不必再进行编译,即以上5个步骤中的第2步和第3步就被省略了,这能大大改善系统的性能。 

(3) 减少网络流量。一个需要数百行T-SQL代码的操作,如果将其创建成存储过程,那么使用一条调用存储过程的语句就可完成该操作。这样就可避免在网络上发送数百行代码,从而减少了网络负荷。

(4) 可作为安全机制使用。管理员可以不授予用户访问存储过程中涉及的表的权限,而只授予执行存储过程的权限。这样,既可以保证用户通过存储过程操纵数据库中的数据,又可以保证用户不能直接访问存储过程中涉及的表。用户通过存储过程来访问表,所能进行的操作是有限制的,从而保证了表中数据的安全性。

 

2.存储过程的类型

(1) 系统存储过程

在SQL Server中的许多管理工作是通过执行系统存储过程来完成的。系统存储过程创建和保存在master数据库中,都以sp_为名称的前缀。系统存储过程是SQL Server系统自带的,具有执行系统存储过程权限的用户,可在master数据库之外直接调用。一般情况下,系统存储过程执行成功返回0值,若有错误发生返回非0值。

(2) 扩展存储过程

扩展存储过程是以动态链接库(dll)形式存在的外部程序。SQL Server自身带了大量的扩展存储过程安装在master数据库中,扩展存储过程与普通存储过程执行方法相同。 

若扩展存储过程的前缀为sp_,则该扩展存储过程在master数据库之外也可直接调用;否则,必须在扩展存储过程前面加上“master.dbo.”前缀。开发人员可以使用其他编程语言来创建扩展存储过程,编写好扩展存储过程后,可由sysadmin服务器角色的成员在 SQL Server 中注册该扩展存储过程,然后授予其他用户执行该过程的权限。扩展存储过程只能添加到 master 数据库中,利用扩展存储过程可以扩展SQL Server的功能。

(3) 用户存储过程

用户存储过程是由用户根据实际问题的需要所创建的存储过程。固定服务器角色sysadmin 的成员可根据实际需要在master数据库中创建用户存储过程,若使用sp_做存储过程的前缀,则该存储过程在任何位置均可直接调用,否则,必须在该存储过程前面加上“master.dbo.”前缀。对于在用户数据库中创建的存储过程,最好不要使用sp_作为其名称的前缀,否则如果该存储过程与系统存储过程同名,则该存储过程永远不会被执行。并且若在该用户数据库之外调用该存储过程,也必须在存储过程名的前面加上“用户数据库名.所有者名.”前缀才能找着、执行该存储过程。

 

ps:其实还很想知道怎样使用数据库才能尽其能,注意那些事项。

--end.

posted on 2012-10-19 23:58  子夜双鱼  阅读(277)  评论(0编辑  收藏  举报