Spring事务

A 事务定义:

    事务是指多个操作单元组成的合集,这些单元操作是不可分割的整体,所有操作要么都不成功,要么都成功

B 四个属性(ACID):

    原子性 atomicity: 即事务是不可分割的最小工作单元,事务内的操作要么全做,要么全不做
    一致性 consistency: 在事务执行前数据库的数据处于正确的状态,而事务执行完成后数据库的数据还是应该处于正确的状态,即数据完整性约束没有被破坏如银行转帐,A转帐给B,必须保证A的钱一定转给B,一定不会出现A的钱转了但B没收到,否则数据库的数据就处于不一致 不正确 的状态
    隔离性 isolation: 并发事务执行之间互不影响,在一个事务内部的操作对其他事务是不产生影响,这需要事务隔离级别来指定隔离性
    持久性 durability: 事务一旦执行成功,它对数据库的数据的改变必须是永久的,不会因比如遇到系统故障或断电造成数据不一致或丢失

C 事务的类型:

    1  本地事务和分布式事务
        1> 本地事务:普通事务,只涉及一个数据源,保证在该数据库上操作的ACID
        2> 分布式事务:涉及两个或多个数据源的事务,由跨越多台同类或异类的多个数据源的事务共同组成,分布式事务旨在保证这些本地事务的所有操作的ACID

    2 Java中事务类型分为JDBC事务和JTA事务

    3 按是否通过编程实现事物控制
        分为声明式事务:通过XML配置或者注解实现, 无侵入,不影响业务逻辑的实现
        编程式事:通过代码在业务逻辑中需要管理事务时自行实现,粒度更小,侵入式

D Spring事务隔离级别

     ISOLATION_DEFAULT : 用底层数据库的默认隔离级别

    ISOLATION_READ_UNCOMMITTED
(未提交读): 最低隔离级别,事务还未提交,就可被其他事务读取(会出现幻读,脏读,不可重复读)

    ISOLATION_READ_COMMITTED
(提交读): 事务提交后才能被其他事务读取(禁止其他事务读取到未提交事务的数据,会幻读,不可重复读),sql server默认级别

    ISOLATION_REPEATABLE_READ
(可重复读): 保证多次读取同一个数据时,读到的值都和事务开始时的内容一致,禁止读到其他未提交事务的数据(基本可防止脏读,不可重复读,会出现幻读)(MySql默认级别,更改可通过set transaction isolation level 级别)

    ISOLATION_SERIALIZABLE
(序列化): 代价最高但最是可靠(能防止脏读,不可重复读,幻读)


E Spring事务传播行为
    PROPAGATION_REQUIRED: 支持当前事务,如当前没有事务,新建一个

    PROPAGATION_SUPPORTS
: 支持当前事务,如当前没有事务,以非事务执行

    PROPAGATION_MANDATORY
: 支持当前事务,如当前没有事务,抛出异常(强制一定要在一个已经存在的事务中执行,业务方法不可独自发起自己的事务)

    PROPAGATION_REQUIRES_NEW: 始终新建一个事务,如已经存在事务,则把原事务挂起

    PROPAGATION_NOT_SUPPORTED
: 不支持当前事务,始终以非事务方式执行,如当前事务存在,挂起该事务

    PROPAGATION_NEVER
: 不支持当前事务 如果当前事务存在,则引发异常

    PROPAGATION_NESTED
: 如果当前事务存在,则在嵌套事务中执行,如果当前没有事务,则执行与 PROPAGATION_REQUIRED 类似的操作(注意: 当应用到JDBC时,只适用JDBC 3.0以上驱动)

F Spring事务支持
    Spring支持事务管理的核心是事务管理器抽象,对不同的数据访问框架通过实现策略接口PlatformTransactionManager,从而支持多种数据访问框架的事务管理
    1 事务管理器, spring提供了多种内置事务管理器以支持不同数据源,常见的事务管理器有:
1> org.springframework.jdbc.datasource.
DataSourceTransactionManager
对javax.sql.DataSource类型的数据源提供事务支持,适用于JDBC,Mybatis等框架事务管理

2> HibernateTransactionManager: 对org.hibernate.SessionFactory类型的数据源提供事务支持,适用于集成Hibernate框架时的事务管理

3> org.springframework.transaction.jta.
JtaTransactionManager: 对分布式事务管理的支持,将事务管理委托给JavaEE应用服务器,或自定义本地JTA事务管理器,嵌套到应用程序中实现事务管理

    以上内置事务管理器都继承了
     AbstractPlatformTransactionManager , AbstractPlatformTransactionManager实现了 PlatformTransactionManager 接口


    2 Spring分布式事务配置

G Spring编程式事务

    PlatformTransactionManager,TransactionTemplate


H Spring声明式事务

    1 <tx:advice>+<aop:config> 

 
 
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
</bean>

<tx:advice id="txAdvice" transaction-manager="transactionManager">
    <tx:attributes>
        <tx:method name="add*" propagation="REQUIRED"/>
        <tx:method name="save*" propagation="REQUIRED"/>
        <tx:method name="insert*" propagation="REQUIRED"/>
        <tx:method name="del*" propagation="REQUIRED"/>
        <tx:method name="remove*" propagation="REQUIRED"/>
        <tx:method name="edit*" propagation="REQUIRED"/>
        <tx:method name="update*" propagation="REQUIRED"/>
        <tx:method name="get*" read-only="true"/>
        <tx:method name="*" read-only="true"/>
    </tx:attributes>
</tx:advice>

<aop:config>
    <aop:pointcut id="pointcut" expression="(execution(* com.dr.service.*.*(..)) or execution(* com.system.service.*.*(..)))"/>
    <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut"/>
</aop:config>
 

    2 @Transactional + <tx:annotation-driven transaction-manager="" /> 

        

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
</bean>

<tx:annotation-driven transaction-manager="transactionManager"/>
@Transactional注意点
如果在接口、实现类或方法上都指定了@Transactional,则优先级为: 方法 > 实现类 > 接口

建议只在实现类或实现类的方法上使用@Transactional,不要直接在接口上使用
因为,如果使用JDK代理机制(基于接口的代理)没有问题;但如果使用CGLIB代理(继承)机制时会遇到问题,原因是CGLIB代理使用基于类的代理而不是接口,此时接口上的@Transactional注解“不能被继承”


I ACID相关概念

    丢失更新: 多个事务同时更新一行数据,后一个事务的更新会覆盖掉前面事务的更新,从而导致前面事务更新的数据丢失,这是由于没有加锁造成的

    幻读: 同样的事务操作过程中,不同时间段多次(不同事务)读取同一数据,读取到的内容不一致(一般是行数变多或变少)

    脏读: 一个事务读取到另外一个未提及事务的内容

    不可重复读: 同一事务中,多次读取内容不一致(一般行数不变,而内容变了)

    幻读与不可重复读的区别: 幻读测重于插入与删除,第二次查询比第一次查询数据变少或变多了; 而不可重复读侧重于修改,第二次的查询结果和一次查询结果不一致,即第一次的结果已经不可重现了

    数据库隔离级别越高,执行代价越高,并发执行能力越差,因此在实际项目开发使用时要综合考虑,为了考虑并发性能一般使用提交读隔离级别,它能避免丢失更新和脏读,尽管不可重复读和幻读不能避免,但可以在可能出现的场合使用悲观锁或乐观锁来解决这些问题

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值