`

Transaction 事务

    博客分类:
  • J2EE
阅读更多
   
数据库事务四特性ACID:
原子性(Atomicity):事务中的操作为一个不可拆分的原子单元,要么全部执行,要么都不执行。
一致性(Consistency):一个事务执行前后数据库都必须处于一致性状态。“数据库的一致性状态”指的是数据完整且满足所有的完整性约束。为了保证数据库的这种一致性,如果一个事务在某步执行失败,则之前所有对数据库的修改必须回滚。
隔离性(Isolation):同时并发执行的多个事务是相互隔离的,不能影响到彼此的执行。即一个事务正在操作的数据应该封锁起来,不被其它企图进行修改的事务看到。
持久性(Durability):事务成功执行后它对数据库的修改是永久的,即使系统出现故障也不受影响。



隔离级别(Isolation Levels):
当并发执行的多个事务同时操作一样的数据时,可能会存在以下的并发异常(Concurrency Anomalies)(这里所说的修改都泛指Update/Insert/Delete):
脏读(Dirty Read):
一个事务读到了其他事务尚未提交的修改。若另一个事务回滚,第一个事务读到的就是彻头彻尾的脏数据。
丢失更新(Lost updates):
并发执行的两个事务都对同一条数据记录做了更新操作并提交,后面的事务提交覆盖了前面事务的提交结果。
不可重复读(Non-repeatable Read):
一个事务两次相同条件的查询读取之间,结果集中的某一条数据记录被另一个事务更新。第一个事务对这条数据记录两次的读取结果就出现了不一致,即该条记录第一次的读取值“不可重复(再现)”。
幻读(Phantom Read):
一个事务两次相同条件的查询读取之间,另一个事务增加或删除了符合第一个事务第一次读取结果的某几条数据记录。第一个事务两次读取到的结果集就出现了记录数上的不一致,产生同样的查询条件却"多了几条记录"或"少了几条记录"的幻觉。
引用
不可重复读和幻读很像,他们的区别再说的详细点:
不可重复读的重点是更新:同样的条件,你读取过的数据,再次读取出来发现值不一样了;
幻读的重点是新增或删除:同样的条件,第1次和第2次读出来的记录数不一样.

为了保证数据库事务四特性ACID中的隔离性,避免出现上面所说的这些并发异常,数据库的事务层面上可以:
确保事务未提交前的修改不被其他事务看到,就可以避免脏读;
事务锁定其正在操作的行(即加行级锁(Row-level lock)),就可以避免丢失更新、不可重复读和因删除而引发的幻读;
事务锁定其正在操作的表(即加表级锁(Table-level lock)),就可以完全避免丢失更新、不可重复读和幻读。
这正是数据库隔离级别的由来:
隔离级别是否存在脏读?是否存在丢失更新&不可重复读?是否存在幻读?举例
未提交读(READ_UNCOMMITTED)YYY
提交读(READ_COMMITTED)NYYOracle
可重复读(REPEATABLE_READ)NNYMysql
序列化读(SERIALIZABLE)NNN
隔离级别越高,容错能力自然越高,但并发性能越低;反之,隔离级别越低,并发性能越高。





Spring AOP 声明式事务管理(未完,或有错)
相较于硬编码方式实现的事务管理(如JDBC),基于Spring AOP来实现事务管理显然有巨大的优势,可以让我们从繁琐的事务处理代码中解放出来。区别于硬编码方式的事务管理(Programmatic Transaction Management),我们叫它声明式事务管理(Declarative Transaction Management)。
Spring声明式事务管理既可基于XML配置方式实现,亦可基于Annotation注解方式来实现。
你在使用Spring的声明式事务管理时,有以下几个问题就得搞清楚:
引用
参考的必要,贴一段典型的JDBC事务处理代码片断:http://topic.csdn.net/u/20090729/21/259c32d7-c89a-4726-9385-f024c75a47bf.html
try {
    conn =DriverManager.getConnection("url","username","userpwd";
    conn.setAutoCommit(false);//禁止自动提交,设置回滚点
    stmt = conn.createStatement();
    stmt.executeUpdate("alter table …"); //数据库更新操作1
    stmt.executeUpdate("insert into table …"); //数据库更新操作2
    conn.commit(); //事务提交
}catch(Exception ex) {  
  ex.printStackTrace();
  try {
      conn.rollback(); //操作不成功则回滚
  }catch(Exception e) {
        e.printStackTrace();
    }
}

1 对单个事务,其边界boundary,或说其scope在哪里?
页面硬编码的方式如JDBC,事务的边界起于conn.setAutoCommit(false),止于conn.commit()|conn.rollback(),spring的声明式事务,边界在哪里?
对单个事务,不考虑传播,Spring的声明式事务在指定方法执行前开启事务,指定方法执行后关闭事务。boundary就是方法的边界,scope也就是该方法里。
2 单个spring事务的粒度granularity,或说级别可以控制到什么范围?
对单个事务,页面硬编码方式可以在代码层面任意控制其粒度大小,spring声明式事务的粒度是如何的那?spring AOP的切入点只支持方法级的,所以基于此的声明式事务,在不考虑传播的情况下,其事务的粒度是方法级的,最小能控制到的就是整个方法内(The Spring Framework's declarative transaction management is similar to EJB CMT in that you can specify transaction behavior (or lack of it) down to individual method level. Ref http://static.springsource.org/spring/docs/3.0.x/reference/transaction.html#transaction-declarative
3 何时触发事务的commit或rollback?
典型的JDBC代码,我们在try里执行完数据库操作后commit,在catch到异常后rollback,那spring的声明式事务中,commit和rollback都是何时触发的那?
一个加了声明式事务的service方法,正确执行结束后commit;若有异常发生,按照spring的异常触发事务回滚策略回滚:http://wuaner.iteye.com/blog/583943
4 事务在方法间的传播?
JDBC的事务是通过Connection实例对象控制的(JDBC transactions are controlled through the Connection object),这也就意味着一个jdbc连接(Connection实例)只能工作在一个事务下(the connection can only work on one transaction at a time)。如果一个大的逻辑业务操作,需要调用多个CRUD方法,我们想让这多个方法在一个事务下,最终无非就是通过让他们公用一个Connection来实现 (例子: http://blog.csdn.net/qjyong/article/details/5464835)。既然spring的声明式事务,其事务边界就是添加了事务的方法的边界,那遇到平级多个方法调用、方法中调另一个方法等情况时,是怎么处理事务的那?这就要考虑spring的事务传播特性 Propagation:
传播特性说明
PROPAGATION_NEVERExecute non-transactionally, throw an exception if a transaction exists.
PROPAGATION_NOT_SUPPORTEDExecute non-transactionally, suspend the current transaction if one exists.
PROPAGATION_SUPPORTSSupport a current transaction, execute non-transactionally if none exists.
PROPAGATION_MANDATORYSupport a current transaction, throw an exception if none exists.
PROPAGATION_REQUIREDSupport a current transaction, create a new one if none exists.  (Default)
PROPAGATION_NESTEDExecute within a nested transaction if a current transaction exists, behave like PROPAGATION_REQUIRED else.
PROPAGATION_REQUIRES_NEWCreate a new transaction, suspend the current transaction if one exists.
很多人都愿意在 <tx:method /> 或 @Transactional 上配置propagation为REQUIRED;spring默认的就是REQUIRED,我不知道这样做目的是什么。
NESTED和REQUIRES_NEW有什么区别呢?参见:
http://forum.spring.io/forum/spring-projects/data/7372-propagation-nested-versus-propagation-requires-new
引用
PROPAGATION_REQUIRES_NEW starts a new, independent "inner" transaction for the given scope. This transaction will be committed or rolled back completely independent from the outer transaction, having its own isolation scope, its own set of locks, etc. The outer transaction will get suspended at the beginning of the inner one, and resumed once the inner one has completed.

Such independent inner transactions are for example used for id generation through manual sequences, where the access to the sequence table should happen in its own transactions, to keep the lock there as short as possible. The goal there is to avoid tying the sequence locks to the (potentially much longer running) outer transaction, with the sequence lock not getting released before completion of the outer transaction.

PROPAGATION_NESTED on the other hand starts a "nested" transaction, which is a true subtransaction of the existing one. What will happen is that a savepoint will be taken at the start of the nested transaction. if the nested transaction fails, we will roll back to that savepoint. The nested transaction is part of of the outer transaction, so it will only be committed at the end of of the outer transaction.

Nested transactions essentially allow to try some execution subpaths as subtransactions: rolling back to the state at the beginning of the failed subpath, continuing with another subpath or with the main execution path there - all within one isolated transaction, and not losing any previous work done within the outer transaction.

For example, consider parsing a very large input file consisting of account transfer blocks: The entire file should essentially be parsed within one transaction, with one single commit at the end. But if a block fails, its transfers need to be rolled back, writing a failure marker somewhere. You could either start over the entire transaction every time a block fails, remembering which blocks to skip - or you mark each block as a nested transaction, only rolling back that specific set of operations, keeping the previous work of the outer transaction. The latter is of course much more efficient, in particular when a block at the end of the file fails.



Sources:
http://static.springsource.org/spring/docs/3.0.x/reference/transaction.html
Spring @Transactional boundaries
http://stackoverflow.com/questions/6363683/springy-transactional-boundaries
Spring声明式事务管理源码解读之事务开始:
http://www.iteye.com/topic/87426
Spring声明式事务管理源码解读之事务提交:
http://www.iteye.com/topic/89072
分享到:
评论

相关推荐

    (精选)CHI协议,transaction事务汇总

    CHI协议,transaction事务汇总: 1.部分事务分为ptl/full ,这里不做区分。 2.事务名基本可以“望文生义”,也就是我们代码所推荐的“命名即注释”。 3.部分事务的行为并不完全确定,个人推测。 4.针对request type...

    Spring在Transaction事务传播行为种类

    ### Spring中的Transaction事务传播行为种类详解 #### 一、引言 在开发基于Spring框架的应用程序时,事务管理是确保数据一致性的重要手段之一。Spring框架提供了丰富的事务管理功能,其中包括了事务传播行为...

    transaction事务

    根据给定的信息,本文将详细解析“transaction事务”这一核心概念及其在数据库操作中的应用,特别是结合提供的代码示例来探讨事务处理的具体实现方法。 ### 一、事务(Transaction)的基本概念 事务是数据库中一系列...

    springboot-transaction事务

    - 事务管理器(Transaction Manager):在Spring Boot中,如果检测到JPA或Hibernate,将会自动配置一个`PlatformTransactionManager`实例。 2. **JPA集成** - JPA是Java提供的ORM(Object-Relational Mapping)...

    springtransaction 事务管理

    在实际项目中,`springtransaction`工程可能是包含了一个完整的示例,用于演示如何在MyEclipse环境中配置和使用Spring的事务管理功能。开发者可以通过导入此工程,学习和实践Spring事务管理的配置与使用,从而更好地...

    C# 执行Transaction事务的一般例子

    C# 执行Transaction事务的一般例子,创建SqlTransaction 对象并用SqlConnection对象的BeginTransaction()方法开始事务,将Transaction属性设置为上面所生成的SqlTransaction对象。 运行环境:Visual Studio2010

    TCC-Transaction分布式事务DEMO

    在这个名为"TCC-Transaction分布式事务DEMO"的项目中,我们将深入探讨TCC模式以及如何在基于Mysql数据库的环境中实现它。 **TCC模式详解** TCC(Try-Confirm-Cancel)是一种补偿型的分布式事务处理模式,主要由三...

    Principles of transaction processing

    根据提供的文件信息,可以提炼出以下与“Principles of transaction processing”相关的知识点: 1. 事务处理的原理 事务处理系统是计算机系统的一个重要组成部分,它涉及到如何高效、安全地处理各种事务。事务处理...

    数据库管理与保护-PPT课件.ppt

    Begin Transaction事务的定义开始;Commit Transaction提交事务;RollBack Transaction取消事务。 并发控制是数据库管理系统的另一个重要部分。并发控制是指在多个事务并发执行时,如何确保事务之间的隔离性和一致...

    基于Hyperf的TCC分布式事务-tcc-transaction.zip

    本项目"基于Hyperf的TCC分布式事务-tcc-transaction.zip"提供了在Hyperf框架下实现TCC事务的示例,帮助开发者理解和应用TCC模式。 首先,我们需要了解Hyperf。Hyperf是一款基于Swoole 4.4+开发的高性能、全异步的...

    javax.transaction.jar

    【javax.transaction.jar】是Java平台上的一个核心组件,主要用于处理分布式环境中的事务管理。这个库包含了一组接口和类,这些接口和类定义了事务管理的API,使得开发者能够在Java应用程序中实现事务处理的规范。在...

    C#中调用Transaction

    本文将深入探讨“C#中调用Transaction”的相关知识点,包括事务的基本概念、事务的特性、如何在C#代码中创建和管理事务,以及与数据库交互时事务的应用。 ### 1. 事务基本概念 事务是数据库操作的一组逻辑单元,它...

    SQLServer存储过程中事务的使用方法

    1. **开启事务**:使用`BEGIN TRANSACTION`语句开启一个事务。这标志着事务的开始,所有的SQL操作将在同一个事务中执行,直到事务被提交或回滚。 ```sql begin transaction ``` 2. **执行SQL操作**:在开启事务后...

    触发器文档

    标记事务类似于命名事务,但不提供一个显式的名字,而是直接通过`BEGIN TRANSACTION`启动。例如: ```sql begin transaction RoyaltyUpdate; go use pubs; go update roysched set royalty = royalty * 1.10 where ...

    Transaction Rollback 事务 让你的对象支持事务

    难道只要数据库连接才支持事务?答案肯定不是,因为COM+同样支持事务,一般的对象要支持事务需要怎样处理? 自行实现所有细节,比如说银行的提款机模拟,在Withdraw的代码中检查支取金额后的余额或者检查支取金额的...

    Transaction 分布式事物的应用举例

    自定义事物类,以及 System....System.Transactions 基础结构通过支持在 SQL Server、ADO.NET、MSMQ 和 Microsoft 分布式事务协调器 (MSDTC) 中启动的事务,使事务编程在整个平台上变得简单和高效、看来没别的对象了。

    Transaction

    在IT行业中,事务(Transaction)是数据库操作的核心概念,它确保了数据的一致性和完整性。在分布式系统和多用户环境中,事务处理对于防止数据错误和保持数据一致性至关重要。本篇文章将深入探讨“Transaction”这一...

    Distributed Transaction Processing The XA Specification.pdf

    3. 事务管理器(Transaction Manager):负责协调全局事务的整个生命周期,包括协调事务分支的提交或回滚,以及处理故障恢复。 4. 资源管理器(Resource Manager):负责管理对单一数据资源的访问,例如数据库、...

    uvm golden reference

    驱动器用于与待测设备(DUT)的接口进行交互,它从序列器接收事务(transaction),然后将这些事务应用到DUT上。 3. uvm_monitor 监视器负责观察DUT的接口,收集信号信息,并将这些信息转化为事务(transaction)...

Global site tag (gtag.js) - Google Analytics