话说事务相关知识

前言

自己之前转载的文章来说Spring中事务的隔离级别和传播行为
http://blog.csdn.net/gao36951/article/details/38274275,还有就是关于以mysql为例的讲解数据库隔离级别的http://blog.csdn.net/gao36951/article/details/38316201但是过一段时间就忘记了,而且还会把数据库的隔离级别混淆起来。今天就彻底研究了一下,解除这个迷惑。

1.1 事务的四大特性CUID

事务(Transaction)是并发控制的单位,是用户定义的一个操作序列。这些操作要么都做,要么都不做,是一个不可分割的工作单位。通过事务,SQL Server能将逻辑相关的一组操作绑定在一起,以便服务器保持数据的完整性。
事务通常是以BEGIN TRANSACTION开始,以COMMIT或ROLLBACK结束。
COMMIT表示提交,即提交事务的所有操作。具体地说就是将事务中所有对数据库的更新写回到磁盘上的物理数据库中去,事务正常结束。
ROLLBACK表示回滚,即在事务运行的过程中发生了某种故障,事务不能继续进行,系统将事务中对数据库的所有以完成的操作全部撤消,滚回到事务开始的状态。

事务的特性(ACID特性)
A:原子性(Atomicity)
事务是数据库的逻辑工作单位,事务中包括的诸操作要么全做,要么全不做。
B:一致性(Consistency)
事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。
C:隔离性(Isolation)
一个事务的执行不能被其他事务干扰。
D:持续性/永久性(Durability)
一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。

1.2 JDBC中的数据隔离级别

如果DBMS支持事务处理,它必须有某种途径来管理两个事务同时对一个数据库进行操作时可能发生的冲突。用户可指定事务隔离级别,以指明DBMS应该花多大精力来解决潜在冲突。例如,当事务更改了某个值而第二个事务却在该更改被提交或还原前读取该值时该怎么办。

  假设第一个事务被还原后,第二个事务所读取的更改值将是无效的,那么是否可允许这种冲突?JDBC用户可用以下代码来指示DBMS允许在值被提交前读取该值(”dirty读取”),其中con是当前连接:
con.setTransactionIsolation(TRANSACTION_READ_UNCOMMITTED);

   事务隔离级别越高,为避免冲突所花的精力也就越多。Connection接口定义了五级,其中最低级别指定了根本就不支持事务,而最高级别则指定当事务 在对某个数据库进行操作时,任何其它事务不得对那个事务正在读取的数据进行任何更改。通常,隔离级别越高,应用程序执行的速度也就越慢(由于用于锁定的资 源耗费增加了,而用户间的并发操作减少了)。在决定采用什么隔离级别时,开发人员必须在性能需求和数据一致性需求之间进行权衡。当然,实际所能支持的级别 取决于所涉及的DBMS的功能。

  当创建Connection对象时,其事务隔离级别取决于驱动程序,但通常是所涉及的数据库的缺省 值。用户可通过调用setIsolationLevel方法来更改事务隔离级别。新的级别将在该连接过程的剩余时间内生效。要想只改变一个事务的事务隔离 级别,必须在该事务开始前进行设置,并在该事务结束后进行复位。我们不提倡在事务的中途对事务隔离级别进行更改,因为这将立即触发commit方法的调 用,使在此之前所作的任何更改变成永久性的。

JDBC的数据隔离级别设置:

JDBC 数据库隔离级别 数据访问情况
TRANSACTION_READ_UNCOMMITTED ur 就是俗称“脏读”(dirty read),在没有提交数据时能够读到已经更新的数据
TRANSACTION_READ_COMMITTED cs 在一个事务中进行查询时,允许读取提交前的数据,数据提交后,当前查询就可以读取到数据。update数据时候并不锁住表
TRANSACTION_REPEATABLE_READ rs 在一个事务中进行查询时,不允许读取其他事务update的数据,允许读取到其他事务提交的新增数据
TRANSACTION_SERIALIZABLE rr 在一个事务中进行查询时,不允许任何对这个查询表的数据修改。

1.2.1 JDBC事务隔离级别

    为了解决与“多个线程请求相同数据”相关的问题,事务之间用锁相互隔开。多数主流的数据库支持不同类型的锁;因此,JDBC API 支持不同类型的事务,它们由 Connection 对象指派或确定。在 JDBC API 中可以获得下列事务级别:

TRANSACTION_NONE 说明不支持事务。

TRANSACTION_READ_UNCOMMITTED 说明在提交前一个事务可以看到另一个事务的变化。这样脏读、不可重复的读和虚读都是允许的。

TRANSACTION_READ_COMMITTED 说明读取未提交的数据是不允许的。这个级别仍然允许不可重复的读和虚读产生。

TRANSACTION_REPEATABLE_READ 说明事务保证能够再次读取相同的数据而不会失败,但虚读仍然会出现。

TRANSACTION_SERIALIZABLE 是最高的事务级别,它防止脏读、不可重复的读和虚读。

    为了在性能与一致性之间寻求平衡才出现了上面的几种级别。事务保护的级别越高,性能损失就越大。 
    假定您的数据库和 JDBC 驱动程序支持这个特性,则给定一个 Connection 对象,您可以明确地设置想要的事务级别:
    conn.setTransactionLevel(TRANSACTION_SERIALIZABLE) ; 
    可以通过下面的方法确定当前事务的级别:
        int level = conn.getTransactionIsolation();
        if(level == Connection.TRANSACTION_NONE)
         System.out.println("TRANSACTION_NONE");
        else if(level == Connection.TRANSACTION_READ_UNCOMMITTED)
         System.out.println("TRANSACTION_READ_UNCOMMITTED");
        else if(level == Connection.TRANSACTION_READ_COMMITTED)
         System.out.println("TRANSACTION_READ_COMMITTED");
        else if(level == Connection.TRANSACTION_REPEATABLE_READ)
         System.out.println("TRANSACTION_REPEATABLE_READ");
        else if(level == Connection.TRANSACTION_SERIALIZABLE)
         System.out.println("TRANSACTION_SERIALIZABLE");

1.3 Spring中的事务隔离级别

使用aop配置事务的时候,除了默认的隔离级别其它四种是和JDBC中的隔离级别相对应的

Isolation[ˌaɪsəˈleɪʃən] 隔离: 属性一共支持五种事务设置,具体介绍如下:
1、 DEFAULT 使用数据库设置的隔离级别 ( 默认 ) ,由 DBA 默认的设置来决定隔离级别 .
2、READ_UNCOMMITTED 会出现脏读、不可重复读、幻读 ( 隔离级别最低,并发性能高 )
3、READ_COMMITTED 会出现不可重复读、幻读问题(锁定正在读取的行)
4、REPEATABLE_READ 会出幻读(锁定所读取的所有行)
5、SERIALIZABLE 保证所有的情况不会发生(锁表)

1.4 事务的传播特性propagation

  1. PROPAGATION_REQUIRED: 如果存在一个事务,则支持当前事务。如果没有事务则开启
  2. PROPAGATION_SUPPORTS: 如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行
  3. PROPAGATION_MANDATORY: 如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常。
  4. PROPAGATION_REQUIRES_NEW: 总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起。
  5. PROPAGATION_NOT_SUPPORTED: 总是非事务地执行,并挂起任何存在的事务。
  6. PROPAGATION_NEVER: 总是非事务地执行,如果存在一个活动事务,则抛出异常
  7. PROPAGATION_NESTED:如果一个活动的事务存在,则运行在一个嵌套的事务中. 如果没有活动事务, 则按TransactionDefinition.PROPAGATION_REQUIRED 属性执行

1.5 主流数据库默认的隔离级别

  1. Oracle里支持的隔离级别:read committed/serializable,默认的是read committed
  2. MySQl支持的隔离级别:read uncommitted/read committed/repeatable read/serializable,默认的是repeatable read;

四种并发异常,四种相应的隔离级别参考如下博文
http://blog.csdn.net/bluishglc/article/details/5626009
mysql和oracle中默认隔离级别参考如下博文
http://www.it165.net/database/html/201310/4644.html
Spring事务隔离级别参考如下博文
http://www.cnblogs.com/qqzy168/p/3307284.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值