10. SQL—事务处理控制

Posted 江湖@小小白

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了10. SQL—事务处理控制相关的知识,希望对你有一定的参考价值。

1. 事务控制

事务控制或者事务处理是指数据库系统执行数据库事务的能力,事务是指在逻辑上必须完成的一命令序列的单位。单位工作期是指事务的开始和结束时期。如果在事务中产生错误,那个整个过程可以根据需要被终止,如果每一件事都是正确的,那么结果将会被保存到数据库中。

2. 开始事务处理

所有支持事务处理的系统都必须以一种准确的语法来告诉系统一项事务是如何开始的(不要忘记事务处理只是工作的逻辑分组,它有自己的开始和结束)


使用 PERSONAL ORSCLE7 时,
语法:

SET TRANSACTION
{
	READ ONLY | USE ROLLBACK SEGMENT segment
}

SQL 标准要求每一种数据库的 SQL 解释器都必须支持语句级的读一致,
这就是说,当
某一种语句运行的时候数据必需保持不变。
但是,在许多情况下在一个工作过程中,
必须要求数据保持有效。
而不仅仅是对单个语句。

ORACLE 允许用户用 SET TRSNSACTION 来指定事务的开始。

eg:
检查 BILL TURN 的信息并且保证数据是在这之中是不能改变的sql:

SET TRANSACTION READ ONLY;

SELECT * FROM 
CUSTOMERS
WHERE
NAME = 'Bill Turner';

COMMIT;

分析:

SET TRANSACTION READ ONLY 
允许你锁定一个记录集直到事务结束.

SELECT
LOCK TABLE
SET ROLE
ALTER SESSION
ALTER SYSTEM

选项 USE ROLLBACK SEGMENT 告诉 ORACLE 数据库
提供数据回溯的存储空间段,
这一选项是 ORACLE 对标准的 SQL 的扩展.


SQL Server's Transact-SQL 语言
用下边的方法来实现了开始事务处理的命令

begin {transaction | tran} [transaction_name]


注:
它的实现方法与 ORACLE 的有一些不同,
(SYBASE 不允许你指定 READ ONLY 选项) 
但是 SYBASE 允许你给出事务处理的名字,
从最早的事务到最近发生的事务处理都可以一次退回.

begin transaction new_account;

insert CUSTOMERS 
values 
(
"Izetta Parsons", 
"1285 Pineapple Highway", 
"Greenville", "AL"
32854, 6
);

if exists
(
    select * from
    CUSTOMERS 
    where 
    Name = "Izetta Parsons"
);


begin;
    
begin transaction;
    
insert BALANCES values(1250.76, 1431.26, 8);

end;

else
    
rollback transaction;
    
if exists
(
    select * from 
    BALANCES 
    where 
    Account_ID = 8
);
    

begin;
    
begin transaction;
    
insert ACCOUNTS values(8, 6);
    
end;
    
else;
    
rollback transaction;
    
if exists
(
    select * from 
    ACCOUNTS 
    where
    Account_ID = 8 
    and 
    Customer_ID = 6
);
    
commit transaction;
    
else
    
rollback transaction;
    
go;
    
    
注:
    最开始的事务处理在第 1,
    之后是插入语句,
    你检查了插入确实已经执行了,
	以后,
    第二个事务处理在第 5 行开始,
    这种在事务之中的事务在术语上称为内嵌事务.
    
有一些数据库支持 AUTOCOMMIT 选项,
它可以在 SET 命令中使用.
    
如下:
    
SET AUTOCOMMIT [ON | OFF]
    
注:
    默认情况上 SET AUTOCOMMIT ON 命令在启动时是自动运行的,
    它告诉 SQL 自动确认你所运行的所有的语句,
    如果你不想让这个命令自动运行,
    那么请将它的参数设为 
    NO SET AUTOCOMMIT OFF;
    
    

3. 结束事务处理


在 ORACLE 语法中结束事务处理语句的语法如下:

COMMIT [WORK]
[ COMMENT 'text'| FORCE 'text' [,integer]];

注:

COMMIT 命令将保存在一项事务中所进行的所有的改变,
在开始一项事务处理之前要先运行 COMMIT 命令,
以确保在之前没有事务未被确认.


eg:
下例中,如果 COMMIT 没有收到任何系统错误的情况下它将会执行确认。

 COMMIT;
 
 SET TRANSACTION READ ONLY;
 
 SELECT * FROM
 CUSTOMERS 
 WHERE 
 NAME = 'Bill Turner';
 
 1. 在 ORACLE 中 COMMIT 语句的使用方法如下: 
 SET TRANSACTION;
 
 INSERT INTO CUSTOMERS 
 VALUES
 (
     "John MacDowell", 
     "2000 Lake Lunge Road", 
     "Chicago", "IL", 
     42854, 
     7
 );

 COMMIT;

SELECT * FROM CUSTOMERS;


2. Sybase SQL 使用 COMMIT 的语法方式如下:
begin transaction;

insert into CUSTOMERS 
values
 (
     "John MacDowell", 
     "2000 Lake Lunge Road", 
     "Chicago", "IL", 
     42854, 
     7
 );
 
commit transaction;

go;

select * from CUSTOMERS;

go;


注:
COMMIT WORD 命令与 COMMIT 命令的作用是相同的
(或 Sybase 中的 COMMITTRANSACTION) 


切记 COMMIT 语句一定要与之前的 SET TRANSCATION
或 BEGIN TRANSCATION 语句一致.


4. 取消事务处理

在一个事务处理的过程中,常常会运行一些错误的检查以确认在过程中语句是否运行成功。你可以通过 ROLLBACK 语句来撤销事务中所做的每一项工作,即便工作是成功的也可以撤销。

但是,这必须在 COMMIT 之前,ROLLBACK 语句必须在一个事务之中运行,它可以一直撤销到事务的开始,也就是说,数据库会一直返回到事务处理刚开始的状态。


语法如下:
ROLLBACK [WORK]
[TO[SAVEPOINT] savepoint | FORCE'text']


一个 ORACLE 的命令序列如下:

SET TRANSACTION;

INSERT INTO 
CUSTOMERS 
VALUES
 (
     "Bubba MacDowell", 
     "2222 Blue Lake Way",
     "Austin", "TX",
     39874,
     8
 );

ROLLBACK;

SELECT * FROM CUSTOMERS;

Sybase SQL 的命令序列则如下:

begin transaction;


insert into 
CUSTOMERS 
values
(
    "Bubba MacDowell", 
    "2222 Blue Lake Way", 
    "Austin", "TX", 
    39874, 
    8
)


rollback transaction;

go;

SELECT * FROM CUSTOMERS;

go;


SET TRANSACTION;

SELECT 
CUSTOMERS.NAME, 
BALANCES.CURR_BAL, 
BALANCES.ACCOUNT_ID
FROM 
CUSTOMERS, 
BALANCES
WHERE 
CUSTOMERS.NAME = "Rebecca Little"
AND 
CUSTOMERS.CUSTOMER_ID = BALANCES.ACCOUNT_ID;

UPDATE 
BALANCES 
SET 
CURR_BAL = 'new-value'
WHERE 
ACCOUNT_ID = 6;

COMMIT;

ROLLBACK;


当该对话框在 Sybase SQL 中被载入以后 
将会运行下边的语句:

begin transaction;

select 
CUSTOMERS.Name, 
BALANCES.Curr_Bal, 
BALANCES.Account_ID
from 
CUSTOMERS, 
BALANCES
where 
CUSTOMERS.Name = "Rebecca Little"
and 
CUSTOMERS.Customer_ID = BALANCES.Account_ID;

go;

update 
BALANCES 
set 
Curr_BAL = 'new-value' 
WHERE 
Account_ID = 6;

commit transaction;

go;

rollback transaction;

go;

ROLLBACK 语句将会终止整个事务,
当存在嵌套事务时 ROLLBACK 将会终止掉全部事务,
系统将会返回到事务开始的最初状态.

如果当前没有活动的事务时,ROLLBACKCOMMIT 语句
将不会对数据库产生任何影响
(你可以认为这是一个无效的命令)COMMIT 语句运行以后,
在事务中的所有动作都会得到确认,
这时在使用ROLLBACK命令就太晚了.

5. 在事务中使用保存点

在事务中使用 ROLLBACK 可以取消整个的事务,但是你也可以在你的事务当中使用语句进行部分地确认,在 Sybase 和 Oracle 中都允许你在当前事务中设一个保存点,从这一点开始,如果你使用了 ROLLBACK 命令,那么系统将会回到保存点时的状态,而在保存点之前的语句将会得到确认。


1.在 ORACLE 中创建一个保存点的语法格式如下:
  
  SAVEPOINT savepoint_name;
  
2.在 SYBASE 中创建保存点的语法格式如下:
  
  save transaction savepoint_name;
  
  
3.ORACLE 语法示例:

  SET TRANSACTION;
  
  UPDATE 
  BALANCES 
  SET 
  CURR_BAL = 25000
  WHERE 
  ACCOUNT_ID = 5;
  
  
  SAVEPOINT save_it;
  
  DELETE FROM 
  BALANCES 
  WHERE 
  ACCOUNT_ID = 5;
  
  
  ROLLBACK TO SAVEPOINT save_it;
  
  COMMIT;
  
  SELECT * FROM BALANCES;
  
4.使用 Sybase 语法示例:

    1> begin transaction
    2> update BALANCES set Curr_Bal = 25000 where Account_ID = 5
    3> save transaction save_it
    4> delete from BALANCES where Account_ID = 5
    5> rollback transaction save_it
    6> commit transaction
    7> go
    1> select * from BALANCES
    2> go


分析:
    在上边的例子中创建了一个叫 SAVE_IT 的保存点,
    UPDATE 语句更新了结算平衡表中的 CURR_BAL 列,
    你在其后设置了一个保存点,
    在保存之后,
    你又运行了 DELETE 命令,
    系统退回到了保存点处,
    之后你对事务用 COMMIT 命令进行了确认,
    结果所有在保存点之前的命令得到了确认.



如果你在其后又使用了 ROLLBACK 命令,
那么将会取消当前的事务而不会有任何的改变.

5.在 ORACLE 中的示例:

    SQL> SET TRANSACTION;
    
    SQL> UPDATE BALANCES SET CURR_BAL = 25000 WHERE ACCOUNT_ID = 5;
    
    SQL> SAVEPOINT save_it;
    
    SQL> DELETE FROM BALANCES WHERE ACCOUNT_ID = 5;
    
    SQL> ROLLBACK TO SAVEPOINT save_it;
    
    SQL> ROLLBACK;
    
    SQL> SELECT * FROM BALANCES;
    
    
6.在 Sybase SQL 语句中的示例: 

    1>begin transaction
    
    2>update BALANCES set Curr_Bal = 25000 where Account_ID = 5
    
    3>save transaction save_it
    
    4>delete from BALANCES where Account_ID = 5
    
    5>rollback transaction save_it
    
    6>rollback transaction
    
    7>go
    
    1>select * from BALANCES
    
    2>go
  

6. 总结

事务可以被定义为一个有组织的工作单元,事务通常会执行一系列的以前学过的操作,如果由于一些原因使得操作没有如所期望地执行,那么可以在事务中取消这些操作,反之,如果操作全部正确执行了 那么事务中的工作可以确认。


BEGIN TRANSACTION

 statement 1
 statement 2
 statement 3
 
ROLLBACK TRANSACTION

或者

BEGIN TRANSACTION

 statement 1
 statement 2
 statement 3
 
COMMIT TRANSACTION


以上是关于10. SQL—事务处理控制的主要内容,如果未能解决你的问题,请参考以下文章

(4.38)sql server中的事务控制及try cache错误处理

JDBC事务处理

数据库的事务处理和并发控制

来自代码的 Sql 客户端事务与数据库控制的事务

聊聊Spring事务控制策略以及@Transactional失效问题避坑

聊聊Spring事务控制策略以及@Transactional失效问题避坑