Fork me on GitHub

spring事务

  1. spring中实现事务控制的方式,声明式事务注解式事务。 在spring配置文件中配置数据库事务,基于AOP的方式,实现事务的管理,只需要配置切入点和相应的事务传播属性,事务隔离等级,何种异常回滚,就可以实现事务。
    <tx:method name="select*" propagation="REQUIRED" read-only="true" />以这个例子来讲解,name表示以这个前缀命名的方法将受到这个事务配置的控制,propagation表示事务传播属性的设置,默认就是REQUIRED这个属性,表示当前存在事务就添加事务,没有事务就新建事务,这个可以在spring-tx-4.3.xsd文件中看到相关的属性定义
<xsd:attribute name="propagation" default="REQUIRED">
                        <xsd:annotation>
                            <xsd:documentation source="java:org.springframework.transaction.annotation.Propagation"><![CDATA[
    The transaction propagation behavior.
                            ]]></xsd:documentation>
                        </xsd:annotation>
                        <xsd:simpleType>
                            <xsd:restriction base="xsd:string">
                                <xsd:enumeration value="REQUIRED"/>
                                <xsd:enumeration value="SUPPORTS"/>
                                <xsd:enumeration value="MANDATORY"/>
                                <xsd:enumeration value="REQUIRES_NEW"/>
                                <xsd:enumeration value="NOT_SUPPORTED"/>
                                <xsd:enumeration value="NEVER"/>
                                <xsd:enumeration value="NESTED"/>
                            </xsd:restriction>
                        </xsd:simpleType>
                    </xsd:attribute>

其他几种事务传播属性的介绍:
SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行
MANDATORY:如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常
REQUIRES_NEW:创建一个新的事务,如果当前存在事务,则把当前事务挂起
NOT_SUPPORTED:以非事务方式运行,如果当前存在事务,则把当前事务挂起
NEVER:以非事务方式运行,如果当前存在事务,则抛出异常
NESTED:如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务则创建事务
read-only表示是只读事务,提示数据库驱动程序和数据库系统,这个操作不包含修改操作,这个可以进行优化例如不加数据库锁,以减轻事务对数据库的压力。 isolation表示设置事务隔离等级,默认是READ_COMMITTED,这个表示避免脏读,这个也可以在xsd文件中看到相关的定义

<xsd:attribute name="isolation" default="DEFAULT">
                        <xsd:annotation>
                            <xsd:documentation source="java:org.springframework.transaction.annotation.Isolation"><![CDATA[
    The transaction isolation level.
                            ]]></xsd:documentation>
                        </xsd:annotation>
                        <xsd:simpleType>
                            <xsd:restriction base="xsd:string">
                                <xsd:enumeration value="DEFAULT"/>
                                <xsd:enumeration value="READ_UNCOMMITTED"/>
                                <xsd:enumeration value="READ_COMMITTED"/>
                                <xsd:enumeration value="REPEATABLE_READ"/>
                                <xsd:enumeration value="SERIALIZABLE"/>
                            </xsd:restriction>
                        </xsd:simpleType>
                    </xsd:attribute>  

其他几种的隔离等级及含义如下:
READ_UNCOMMITTED:这表示会导致脏读,不可重复读,幻读
READ_COMMITTED:这表示会避免脏读,还是会导致不可重复读,幻读
REPEATABLE_READ:这表示会避免脏读,不可重复读,还是会导致幻读
SERIALIZABLE:这表示会避免脏读,不可重复读,幻读 所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰
这些隔离级别慢慢的增加,级别越高越能保证数据的一致性,但是也会降低系统性能
脏读的含义:当一个事务修改了数据,还未提交,另一个事务读取了数据,这样另一个事务读取到的数据称为脏数据
不可重复读:当一个事务中存在两次读时,第一次读取数据后,另一个事务修改了数据,导致两次读取到的数据不一样,这就是不可重复读
幻读:事务A读取更新记录,事务B对记录进行了删除或者添加操作,A提交查询记录发现更改的记录中多了一条数据被更改
何种异常时将触发事务回滚,spring默认是方法抛出RuntimeException才会触发事务,如果是受检异常是不会触发,如果是要try{}catch(){}捕获了RuntimeException也不会触发事务,解决办法是自己指定触发事务的异常类型,还有在catch中抛出异常或者是使用TransactionAspectSupport.currentTransactionStatus().setRollbackOnly()手动设置事务回滚。
在service中外部调用方法会触发事务,但是在外部调用方法使用内部方法,并且在内部方法上添加了@Transactional注解也没有用,这是由于事物的实现时基于AOP的代理类实现的,所以我们可以获得当前service的代理类对象AopContext.currentProxy()再进行相应的DAO操作。
2. 事务的传播
事务传播的含义:在一个service中可能会调用其他service中的方法,这就涉及到多个事物的问题,这就会导致事务传播的问题
3. 事务的隔离
事务的隔离的含义:为了有效保证并发读取数据的正确性
4. 事务的四大特性ACID
A:原子性:操作的原子性
C:一致性:状态的改变具有一致性
I:隔离性:事务的隔离,相互不受干扰
D:永久性:数据改变具有永久性


最新评论

    还没有人评论...

当当

友情链接

Powered by Python. Copyright © 2017.

鄂ICP备17010875号. All rights reserved.