zoukankan      html  css  js  c++  java
  • oracle事务

    事务定义:

    (1)原子性:要么执行完成,要么不执行。

    (2)一致性:业务逻辑一致性。例如:业务逻辑为,A表新增一条数据,B表需要更新一条数据,这两个操作需要都执行或者都不执行,就是一致性。此时,可以用@Transactional注解实现

    (3)隔离性:多线程需要考虑隔离性,即线程1和线程2需要修改同一个表数据时,其中一个线程看到的要么是另一个线程执行完成或者未执行的结果,不会看到中间数据。

    (4)永久性:事务一旦提交,则持久化保存在数据库中。

    隔离级别

    声明式事务的第二个方面是隔离级别。隔离级别定义一个事务可能受其他并发事务活动活动影响的程度。另一种考虑一个事务的隔离级别的方式,是把它想象为那个事务对于事物处理数据的自私程度。

    在一个典型的应用程序中,多个事务同时运行,经常会为了完成他们的工作而操作同一个数据。并发虽然是必需的,但是会导致一下问题:

    • 脏读(Dirty read)-- 脏读发生在一个事务读取了被另一个事务改写但尚未提交的数据时。如果这些改变在稍后被回滚了,那么第一个事务读取的数据就会是无效的。
    • 不可重复读(Nonrepeatable read)-- 不可重复读发生在一个事务执行相同的查询两次或两次以上,但每次查询结果都不相同时。这通常是由于另一个并发事务在两次查询之间更新了数据。
    • 幻影读(Phantom reads)-- 幻影读和不可重复读相似。当一个事务(T1)读取几行记录后,另一个并发事务(T2)插入了一些记录时,幻影读就发生了。在后来的查询中,第一个事务(T1)就会发现一些原来没有的额外记录。

    在理想状态下,事务之间将完全隔离,从而可以防止这些问题发生。然而,完全隔离会影响性能,因为隔离经常牵扯到锁定在数据库中的记录(而且有时是锁定完整的数据表)。侵占性的锁定会阻碍并发,要求事务相互等待来完成工作。

    考虑到完全隔离会影响性能,而且并不是所有应用程序都要求完全隔离,所以有时可以在事务隔离方面灵活处理。因此,就会有好几个隔离级别。

    隔离级别含义
    ISOLATION_DEFAULT 使用后端数据库默认的隔离级别。
    ISOLATION_READ_UNCOMMITTED 允许读取尚未提交的更改。可能导致脏读、幻影读或不可重复读。
    ISOLATION_READ_COMMITTED 允许从已经提交的并发事务读取。可防止脏读,但幻影读和不可重复读仍可能会发生。
    ISOLATION_REPEATABLE_READ 对相同字段的多次读取的结果是一致的,除非数据被当前事务本身改变。可防止脏读和不可重复读,但幻影读仍可能发生。
    ISOLATION_SERIALIZABLE 完全服从ACID的隔离级别,确保不发生脏读、不可重复读和幻影读。这在所有隔离级别中也是最慢的,因为它通常是通过完全锁定当前事务所涉及的数据表来完成的。

    事务传播行为

    Propagation(key属性确定代理应该给哪个方法添加事务行为。这种属性最重要的部份是传播行为。)有下面选项可供使用:

    • PROPAGATION_REQUIRED--支持当前事务,假设当前没有事务。就新建一个事务。 这是最常见的选择。
    • PROPAGATION_SUPPORTS--支持当前事务,假设当前没有事务,就以非事务方式运行。
    • PROPAGATION_MANDATORY--支持当前事务,假设当前没有事务,就抛出异常。 
    • PROPAGATION_REQUIRES_NEW--新建事务,假设当前存在事务。把当前事务挂起。 
    • PROPAGATION_NOT_SUPPORTED--以非事务方式运行操作。假设当前存在事务,就把当前事务挂起。
    • PROPAGATION_NEVER--以非事务方式运行,假设当前存在事务,则抛出异常。

    举例浅析Spring嵌套事务

    ServiceA {
           
         void methodA() {
             ServiceB.methodB();
         }
      
    }
      
    ServiceB {
           
         void methodB() {
         }
           
    }

    PROPAGATION_REQUIRED

    假如当前正要运行的事务不在另外一个事务里,那么就起一个新的事务 比方说,ServiceB.methodB的事务级别定义为PROPAGATION_REQUIRED, 那么因为执行ServiceA.methodA的时候,ServiceA.methodA已经起了事务。这时调用ServiceB.methodB,ServiceB.methodB看到自己已经执行在ServiceA.methodA的事务内部。就不再起新的事务。而假如ServiceA.methodA执行的时候发现自己没有在事务中,他就会为自己分配一个事务。这样,在ServiceA.methodA或者在ServiceB.methodB内的不论什么地方出现异常。事务都会被回滚。即使ServiceB.methodB的事务已经被提交,可是ServiceA.methodA在接下来fail要回滚,ServiceB.methodB也要回滚

  • 相关阅读:
    解压缩编码列表
    按既定顺序创建目标数组
    整数的各位积和之差
    好数对的数目
    拿硬币
    设计 Goal 解析器
    【求助】win 2008 R2 远程桌面多用户,破解最大连接数2的限制
    Java 字符串拼接 五种方法的性能比较分析 从执行100次到90万次
    Java abstract class 和 interface 的区别
    忘记BIOS超级管理员密码,怎么破解?
  • 原文地址:https://www.cnblogs.com/BonnieWss/p/10860956.html
Copyright © 2011-2022 走看看