zoukankan      html  css  js  c++  java
  • 事务的概念

    一、事务                    

      事务是访问数据库的一个操作序列,数据库应用系统通过事务集来完成对数据库的存取。事物的正确执行是的数据库从一个状态转换成另一个状态。

      事务必须服从ISO/IEC所指定的ACID原则。

    • 原子性(atomicity)。即不可分割性,事务要么全部被执行,要么就全部不被执行。如果事务的所有子事务全部被提交成功(所有的数据库操作被提交),则数据库的状态发生转换;如果子事务执行失败,则其他的子事务的数据库操作被回滚,即数据库回到事务执行的状态之前,不会发生状态转换。
    • 一致性或可串性(consistency)。事务的执行使得数据库从一种正确状态转换成另一种正确状态。 如果事务启动时数据是一致的,那么当这个事物成功后数据库的数据也必须是一致的。  
    • 隔离性(isolation)。在事务提交之前,不允许把该事务对数据的任何改变提供给任何其他事务。
    • 持久性(durability)。事务正确提交后,其结果将永久保存在数据库中,即使在事务提交后有了其他故障,事务的处理结果也会得到保存。
    • 注意:银行存取款中, 事务的执行过程中,必须允许暂时的不一致性,因为无论是A账户取出操作在前还是B账户存入操作在前,这两个操作必然有一个先后顺序,两个操作之间就会产生不一致。于是乎,在原子性和一致性的双重作用之下,事务就能够正确、有效地执行,实现响应的逻辑功能。

      所以说原子性和一致性是有区别的,但是两者又是互补的,不能隔离开来。

    • COMMIT 和 ROLLBACK 在大多数情况下,通过执行COMMIT或者ROLLBACK语句来终止事务。 当执行COMMIT语句时,自从事务启动以来对数据库所做的一切操作就会成为永久--即所有的改变被写入磁盘。         当执行ROLLBACK语句时,自从事务启动以来对数据库所做的一切操作都被撤销,且数据库返回到事务开始之前所处的状态。 不管哪种情况,数据库在事务完成时都保证能回到一致状态。

    二、数据系统的两种事务模式    

    • 自动提交模式:每个SQL语句都是一个独立的事务,当数据库系统执行完一个SQL语句后,会自动提交事务。
    • 手动提交模式:必须由数据库客户端程序显示指定事务开始边界和结束边界。

      MySQL中数据库表常用的分为3种类型:INNODB,BDB和MyISAM,INNODB和BDB属于事务安全类表。

    三、隔离级别          

      对于访问数据库相同数据的多个事务,如果没有采取必要的隔离机制,就会导致并发问题,这些并发问题可归纳为以下几类

    1. 更新遗失:两个事务都同时更新一行数据,一个事务对数据的更新把另一个事务对数据的更新覆盖了。这是因为系统没有执行任何的锁操作,因此并发事务并没有被隔离开来。
    2. 脏读:一个事务读取到另一个事务未提交的更新数据。因为没有最终提交,有可能是不正确的数据。
    3. 不可重复读:一个事务读到另一个事务已提交的更新数据。另一个事务提交前后的数据不一致。
    4. 第二类丢失更新:这是不可重复读中的特例,一个事务覆盖另一个事务已提交的更新数据。
    5. 幻读:一个事务读到另一个事务已提交的新插入的数据(事务1读取记录时事务2增加了记录并提交,事务1再次读取时可以看到事务2新增的记录;)。

      隔离机制(从高到低)如下:

    • 可串行化(Serializable)读加共享锁,写加排它锁。 读取事务可以并发,写事务之间是互斥的,必须一个一个的执行事务。
    • 可重复读(Repeatable Read)读取数据的事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务。避免了不可重复读取和脏读,但是有时可能出现幻读。这可以通过“共享读锁”和“排他写锁”实现。
    • 读已提交数据(Read Committed)读取数据的事务允许其他事务继续访问该行数据,但是未提交的写事务将会禁止其他事务访问该行。该隔离级别避免了脏读,但是却可能出现不可重复读。事务A事先读取了数据,事务B紧接了更新了数据,并提交了事务,而事务A再次读取该数据时,数据已经发生了改变。
    • 读未提交数据(Read Uncommitted)如果一个事务已经开始写数据,则另外一个事务则不允许同时进行写操作,但允许其他事务读此行数据。该隔离级别可以通过“排他写锁”实现。避免了更新丢失,却可能出现脏读。也就是说事务B读取到了事务A未提交的数据

    隔离机制对应产生的问题(Y引起问题):

    隔离机制/并发问题 LU丢失更新 DR脏读 NRR非重复读 SLU二类丢失更新 PR幻读
    未提交读(Read Uncomitted)  N  Y  Y  Y  Y
    提交读(Read Commited)  N     N  Y  Y  Y
    重复读(Repeatable Read)  N  N  N  N  Y
    串行化(Serializable)  N  N  N  N  N

    四、Spring 事务管理和实现    

    这里简单的介绍一下声明式,使用注解方式的事务管理和基于AspectJ的xml配置方式。

      <!-- 事务管理 对mybatis操作数据的事务控制,spring使用jdbc的事务控制类 -->
        <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSource"></property>
        </bean>
        
        <!-- 管理事务的两种方式 -->
        <!-- 1、基于注释的事务,当注释中发现@Transactional时,使用id为“transactionManager”的事务管理器  -->
        <!-- 如果没有设置transaction-manager的值,则spring以缺省默认的事务管理器来处理事务,默认事务管理器为第一个加载的事务管理器 -->
        <tx:annotation-driven transaction-manager="transactionManager"/>
        
        <!-- 2、使用切面实现事务 通知 ,也可以不配置切面管理事务,可以使用annotation方式-->
        <!-- <tx:advice id="txAdvice" transaction-manager="transactionManager">
            <tx:attributes>
                传播行为
                <tx:method name="save*" propagation="REQUIRED"/>
                <tx:method name="delete*" propagation="REQUIRED"/>
                <tx:method name="insert*" propagation="REQUIRED"/>
                <tx:method name="update*" propagation="REQUIRED"/>
                <tx:method name="find*" propagation="SUPPORTS"/>
                <tx:method name="get*" propagation="SUPPORTS"/>
                <tx:method name="select**" propagation="SUPPORTS"/>
            </tx:attributes>
        </tx:advice>

    使用单元测试进行测试事务

    @Transactional
        @Test
        public void getShopUserById(){
            ShopUser shopUser = new ShopUser();
            shopUser.setUserid(6);
            shopUser.setUsername("zhangsan");
            shopUser.setPassword("333");
            shopUser.setCreateTime(Long.parseLong(DateUtil.getString(new Date(), DateUtil.YMDHMS)));
            try {
                shopUserService.insertSelective(shopUser);
                int i = 2/0;
            } catch (Exception e) {
                e.printStackTrace();
                logger.info("ShopControllerTest" + e);
            }
    转载: http://www.cnblogs.com/kristain/articles/2038397.html
    lift is made up of small pleasures. 生活是由各种微小的幸福构成。 日积月累,就会产生意想不到的Miracles。 每一天的坚持,每一天的收获,我与你同在!!
  • 相关阅读:
    面向对象(接口 ,多态)
    面向对象(继承,重写,this,super,抽象类)
    IO(字符流 字符缓冲流)
    ArrayList集合
    字符串常用API
    面向对象(类,封装,this,构造方法)
    不同类型问题代码训练
    java中的方法
    04慕课网《进击Node.js基础(一)》HTTP讲解
    《JavaScript设计模式与开发实践》——第3章 闭包和高阶函数
  • 原文地址:https://www.cnblogs.com/drubber/p/5881076.html
Copyright © 2011-2022 走看看