数据库事务处理

什么是事务

事务就是业务上的一个逻辑单元,它能够保证其中对数据所有的操作,要么全部成功,要么失败。

事务控制语句

COMMIR:提交事务,即把事务中对数据库的修改进行永久保存。

ROLLBACK:回滚事务,即取消对数据库所做的任何修改。

SAVEPOINT:在事务中创建存储点。

ROLLBACKE TO<Savepoin_Name>:将事务回滚到存储点 。

SET TRANSACTION:设置事务的属性。

事务的特性(事务必须具备以下四个属性,简称ACID属性)

1.原子性(Atomicity):事务是一个完整的操作。事务的各步操作是密不可分的

(原子的):要么都执行,要么都不执行。

2.一致性(Consistency):在事务操作前后,数据必须处于一致状态。

3.隔离性(Isolation):对数据进行修改的所有并发事务是彼此隔离的,这表明事务必须是独立的,它不应以任何方式依赖于或影响其他事务。

4.持久性(Durability):事务完成后,它对数据库的修改被永久保持。

示例(原子性)

BEGIN
  UPDATE topic7_account SET
  account_balance=account_balance-5000 WHERE account_id=1001;
  --第一个账户取款5000
   UPDATE topic7_account SET
  account_balance=account_balance+5000 WHERE account_id=1002;
  --第二个账户取款5000
  COMMIT;--提交事务
  EXCEPTION --异常处理
    WHEN OTHERS THEN dbms_output.put_line(‘转账异常,停止转账‘);--当余额不足时执行
    ROLLBACK;--回滚事务
END;

示例(一致性)

--一致性
DECLARE
account_a topic7_account.account_balance%TYPE;--定义接收账户A的余额变量
account_b topic7_account.account_balance%TYPE;--定义接收账户B的余额变量
BEGIN
  SELECT account_balance INTO  account_a FROM topic7_account WHERE account_id=1001;--接收账户A的余额
  SELECT account_balance INTO  account_b FROM topic7_account WHERE account_id=1002; --接收账户B的余额
  dbms_output.put_line(‘转账前账户A的余额‘||account_a);
  dbms_output.put_line(‘转账前账户B的余额‘||account_b);
  dbms_output.put_line(‘转账前两个账户的总余额‘||(account_a+account_b)); --输出两个账户的总额
  UPDATE topic7_account SET account_balance=account_balance-2000 WHERE--账户A转出2000,更新数据
  account_id=1001;
  UPDATE topic7_account SET account_balance=account_balance+2000 WHERE--账户B转入2000,更新数据
  account_id=1002;
  COMMIT;
  SELECT account_balance INTO  account_a FROM topic7_account WHERE account_id=1001;
  SELECT account_balance INTO  account_b FROM topic7_account WHERE account_id=1002;
   dbms_output.put_line(‘转账后账户A的余额‘||account_a);
  dbms_output.put_line(‘转账后账户B的余额‘||account_b);
  dbms_output.put_line(‘转账后两个账户的总余额‘||(account_a+account_b));
  EXCEPTION--当产生异常情况
    WHEN OTHERS THEN
   dbms_output.put_line(‘转账错误停止转账‘);
   ROLLBACK;--回滚,恢复没转账前的状态
   SELECT account_balance INTO  account_a FROM topic7_account WHERE account_id=1001;
  SELECT account_balance INTO  account_b FROM topic7_account WHERE account_id=1002;
  dbms_output.put_line(‘停止转账后账户A的余额‘||account_a);
  dbms_output.put_line(‘停止转账后账户B的余额‘||account_b);
  dbms_output.put_line(‘停止转账后两个账户的总余额‘||(account_a+account_b));
END;

隔离性:事务隔离性要求:在事务的处理过程中,其他事务不能访问该事务中的数据。

事务A:

--账户A修改了数据但未提交
UPDATE topic7_account SET account_balance=account_balance+2000 WHERE account_id=1001;
UPDATE topic7_account SET account_balance=account_balance+2000 WHERE account_id=1002;

事务B:

--事务B也对数据 进行修改
UPDATE topic7_account SET account_balance=account_balance+3000 WHERE account_id=1001;

在这一过程中事务B读取不了正在修改过程的事务A中的数据但是可以得到数据处理前的数据或处理后的数据,体现了隔离性。

事务与事务间都是相对独立的。

读取异常:

脏读:一个事务读取了另一个事务未提及的数据(指一个事务修改了该数据但未提交的情况下,另一个事务也访问了该数据,返回的数据可能存在误差,比如读读取的是事务修改前的数据,而后再次得到的是数据已提交的数据)。

不可重复读:一个 事务读取数据后,然后再次对同一个数据进行读取,期间发现该数据已经被另一个事务修改,导致前后读取的数据不一致。

幻读:一个事务根据相同的查询条件,重新执行查询,返回的记录包含前一次执行查询返回的记录不同行。

ANSI SQL-92标准中定义的事务隔离级别

Read Uncommitted

最低等级的事务隔离,它仅仅保证了读取过程中不会读取到非法数据。

Read Committed

此级别的事务隔离保证了一个书屋不会读取到另一个并行事务已修改但未提交的数据,也就是说,此等级的事务级别避免了“脏读”。

Repeatable Read

此等级的事务隔离避免了“脏读”和 “不可重复读”异常现象的出现。这也意味着,一个事务不可能更新已经由另一个事务读取但未提交的数据。(应用不广泛,带来性能损耗)

Serializable

最高等级的隔离级别,提供了最高等级的隔离机制,三种异常情况都能避免。

SAVEPOINT:在事务中创建存储点

语法:

SAVEPOINT[SAVEPOINT_NAME]

ROLLBACK TO<SAVEPOINT_NAME>:将事务回滚到存储点

BEGIN
  UPDATE topic7_account SET account_balance=account_balance+2000 WHERE account_id=1001;
  SAVEPOINT add_save;--存储点
  UPDATE topic7_account SET account_balance=account_balance-1000 WHERE account_id=1001;
  UPDATE topic7_account SET account_balance=account_balance+1000 WHERE account_id=1002;
  EXCEPTION
    WHEN OTHERS THEN
      dbms_output.put_line(‘转账异常,停止转账‘);
      ROLLBACK TO add_save; --回滚存储点
END;

SET TRANSACTION:设置事务的属性

SET TRANSACTION语句的第一条语句

制定事务的隔离级别

规定回滚事务时所使用的存储空间

对事物命名

设置隔离级别的语法

SET TRANSACTION READ ONLY;(只读情况)

SET TRANSACTION ISOLATION LEVEL READ COMMITTED;(避免脏读异常)

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;(避免脏读,不可重复读 ,幻读异常)

时间: 2024-08-27 11:47:51

数据库事务处理的相关文章

十三、EnterpriseFrameWork框架核心类库之数据库操作(多数据库事务处理)

本章介绍框架中封装的数据库操作的一些功能,在实现的过程中费了不少心思,针对不同数据库的操作(SQLServer.Oracle.DB2)这方面还是比较简单的,用工厂模式就能很好解决,反而是在多数据库同时操作方面走了不少弯路:现在从以下几个方面进行说明: 一.不同数据库操作 此处用到了工厂模式来实现不同数据库操作,看下图 AbstractDatabase是一个抽象类,定义了所有对数据库的操作抽象方法,包括执行一个SQL语句.执行存储过程.事务操作等 [Serializable] public abs

Atitti 数据库事务处理&#160;attilax总结

Atitti 数据库事务处理 attilax总结 1.1. 为什么要传递Connection?1 1.2. 两种事务处理方式,一种是编程式事务处理;一种是声明...2 1.3. 事务隔离级别 2 1.4. 事务传播行为2 1.5. 事务的回滚规则 3 1.6. 声明式事务唯一不足地方是,方法级别,无法做到像编程式事务那样可以作用到代码块级别.3 1.7. 事务对影响记录条数的影响,好像没影响,回滚了也提示修改了一条.Callback没有也不关系..只要不commit,好像就会自动回滚的.4 1.

数据库事务处理机制之事务回滚问题讨论

一.Sql中的事务 概念:事物是一种机制,是一种操作序列,它包含了一组数据库操作命令,这组命令要么全部执行,要么全部不执行.事务是一个不可分割的工作逻辑单元.在数据库系统上执行并发操作时事务是作为最小的控制单元来使用的.多用户登录系统适于使用事务机制. 属性:4大属性: a.原子性:事务时一个完整的操作.b.一致性:当事务完成时,数据库必须处于一致状态.c.隔离性:对数据进行修改的所有并发事务时彼此隔离的.d.持久性:事务完成后,它对于系统的影响是永久性的. 创建 (1)开始事务:begin t

java中的数据库事务处理

/*java使用事务处理,首先要求数据库支持事务,如使用MYSQL的事务功能,就要求mysql的表类型为Innodb,*/ /*InnoDB,是MySQL的数据库引擎之一 与传统的ISAM与MyISAM相比,InnoDB的最大特色就是支持了 ACID兼容的事务(Transaction)功能,类似于PostgreSQL.*///Java事务的类型有三种:JDBC事务.JTA(Java Transaction API)事务.容器事务. // 1.JDBC事务--------java.sql.Conn

JDBC学习笔记(6)——获取自动生成的主键值&amp;处理Blob&amp;数据库事务处理

获取数据库自动生成的主键 [孤立的技术是没有价值的],我们这里只是为了了解具体的实现步骤:我们在插入数据的时候,经常会需要获取我们插入的这一行数据对应的主键值. 具体的代码实现: 1 /** 2 * 获取数据库自动生成的主键 3 */ 4 @Test 5 public void testGetKeyValues(){ 6 Connection connection=null; 7 PreparedStatement preparedStatement=null; 8 ResultSet rs=n

关系型数据库事务处理ACID

ACID,指数据库事务正确执行的四个基本要素的缩写.包含:原子性(Atomicity).一致性(Consistency).隔离性 (Isolation).持久性(Durability).一个支持事务(Transaction)的数据库系统,必需要具有这四种特性,否则在事务过程 (Transaction processing)当中无法保证数据的正确性,交易过程极可能达不到交易方的要求. 原子性整个事务中的所有操作,要么全部完成,要么全部不完成,不可能停滞在中间某个环节.事务在执行过程中发生错误,会被

springBoot(14):使用SQL关系型数据库-事务处理

一.事务的四个特性(ACID) 原子性(Atomicity): 事务是一个原子操作,由一系列动作组成.事务的原子性确保动作要么全部完成,要么完全不起作用. 一致性(Consistency): 一旦事务完成(不管成功还是失败),系统必须确保它所建模的业务处于一致的状态,而不会是部分完成部分失败.在现实中的数据不应该被破坏. 隔离性(Isolation): 可能有许多事务会同时处理相同的数据,因此每个事务都应该与其他事务隔离开来,防止数据损坏. 持久性(Durability): 一旦事务完成,无论发

多数据库事务处理:有待考究

转:http://www.cnblogs.com/tylerdonet/archive/2009/10/30/1592653.html 在一个数据库中实现事务是没什么问题,当时项目中常常会遇到多个数据库交叉事务的情况,这个方法使用两个SqlTransaction 来处理这两个数据库中的事务,当一个更新不成功两个都要回滚. 1 public void TransactionDebug() 2 { 3 4 string sql1 = @"Data Source=XXXXXX;Initial Cata

数据库事务处理差异:可提交读和重复读区别

本文来自于自己的博客:http://www.wangerbao.com/?p=279 Mysql默认事物是重复读(Repeatable Read Isolation Level), PostGres默认事物是提交读(Read Committed Isolation Level),现在根据实例来对比下它们的差别. Mysql: 左边为事物1,右边为事物2. 第一步: 事物1查询,事物2查询,它们的查询结果一致.  第二步: 事物1更新-查询-但是不提交,事物2查询,他们的结果不一致 第三步: 事物