spring的事务处理

事务简介

事务的作用

事务的作用是将一系列操作作为一个整体,一但其中出现问题,会回滚到事务的开始状态。即事务维护了数据的完整性和一致性。

事务的四个特性

原子性:事务的操作是原子不可分割的。

一致性:事务的操作数据保证一致性,不存在一部分改变一部分不改变。

隔离性:隔离性是当多个用户并发访问数据库时,比如操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离。

持久性(Durability):一旦事务完成,无论发生什么系统错误,它的结果都不应该受到影响。

隔离级别导致的问题

如果不考虑隔离性,事务会出现以下问题

脏读

脏读又称无效数据的读出,是指在数据库访问中,事务T1将某一值修改,然后事务T2读取该值,此后T1因为某种原因撤销对该值的修改,这就导致了T2所读取到的数据是无效的。

不可重复读

不可重复读是指一个线程中的事务读取到了另外一个线程中提交的update的数据。

如事务t1查询某人员数据,这时事务t2修改了该人员数据,t1再次查询该人员数据,发现该事务中两次查询的数据不一致。

虚读(幻读)

虚读是指一个线程中的事务读取到了另外一个线程中提交的insert的数据。

如事务t1查询人物数据有6条,事务t2插入1条数据,事务t1再查询人物数据就为7条了。

扫描二维码关注公众号,回复: 1642788 查看本文章

不可重复读和虚读都是事务在执行过程中,有其他事务修改了数据,不过不可重复读是修改,而虚读是添加或删除。

事务的隔离级别

下面是隔离级别与数据问题的关系

读未提交(Read uncommitted)

读已提交(Read committed)

可重复读(Repeatable read)

串行化(Serializable)

脏读

会发生

不会发生

不会发生

不会发生

不可重复读

会发生

会发生

不会发生

不会发生

虚读(幻读)

会发生

会发生

会发生

不会发生

 MySQL支持以上四中隔离级别,默认隔离级别是Repeatable read;Oracle只支持串行化(Serializable)、读已提交(Read committed),默认是读已提交(Read committed)级别。

MySQL查看当前隔离级别:

select @@tx_isolation;

MySQL设置隔离级别语句

set [glogal | session]  transactionisolation level 隔离级别名称;
或
set tx_isolation=’隔离级别名称;’

set tx_isolation='read-committed'

Spring的事务管理

原理

Spring是通过org.springframework.transaction.PlatformTransactionManager接口来实现事务的管理。同时应对不同的场景,提供不同的PlatformTransactionManager实现类来实现管理事务。下面是常见的应用场景。

JDBC事务

如果使用JDBC来进行数据持久化,Spring使用DataSourceTransactionManager类来实现事务管理(mybatis也可以使用JDBC的事务管理,mybatis的事务机制在下延伸中讲解)。Spring配置如下

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

Hibernate事务

如果使用Hibernate来进行数据持久化,Spring使用HibernateTransactionManager类来实现事务管理。Spring配置如下

<bean id="transactionManager"class="org.springframework.orm.hibernate3.HibernateTransactionManager">
         <propertyname="sessionFactory" ref="sessionFactory" />
</bean>

延伸:mybatis的事务机制

MyBatis的事务管理分为两种形式:

一、使用JDBC的事务管理机制:即利用java.sql.Connection对象完成对事务的提交(commit())、回滚(rollback())、关闭(close())等

二、使用MANAGED的事务管理机制:这种机制MyBatis自身不会去实现事务管理,而是让程序的容器如(JBOSS,Weblogic)来实现对事务的管理


Spring事务的隔离级别

Spring除了jdbc的四种事务读未提交ISOLATION_READ_UNCOMMITTED、读已提交ISOLATION_READ_COMMITTED、可重复读ISOLATION_REPEATABLE_READ、串行化ISOLATION_SERIALIZABLE以外,还有ISOLATION_DEFAULT,即使用数据库默认事务隔离级别。

Spring事务的隔离级别配置

<bean id="transactionManager"
      class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
</bean>
<tx:annotation-driven
        order="1" proxy-target-class="true"/>
<tx:advice id="transactionAdvice">
    <tx:attributes>
        <tx:method name="*" isolation="READ_COMMITTED" rollback-for="Exception"/>
    </tx:attributes>
</tx:advice>
<aop:config>
    <aop:pointcut id="transactionPointcut"
                  expression="execution(* com.lc.service..*Service.*(..))"/>
    <aop:advisor pointcut-ref="transactionPointcut"
                 advice-ref="transactionAdvice" order="2"/>
</aop:config>

Spring事务的传播行为

7种传播行为介绍

Spring的事务传播行为有一下7种

REQUIRED:支持当前事务,如果当前没有事务就新创建一个事务

REQUIRES_NEW: 新建事务,如果当前存在事务,就把当前事务挂起。

NOT_SUPPORTED: 在非事务环境下执行,如果当前存在事务,就把当前事务挂起

SUPPORTS: 支持当前事务,如果当前没有事务,就在非事务环境下执行

MANDATORY: 支持当前事务,如果当前没有事务,就抛出异常。

NEVER: 在非事务环境下执行,如果当前存在事务就抛出异常。

NESTED: 如果当前存在事务,则在嵌套事务内执行;如果当前没有事务,则进行与REQUIRED类似的操作;拥有多个可以回滚的保存点,内部回滚不会对外部事务产生影响。它只对DataSourceTransactionManager事务管理器起效。

事务传播行为的理解,事务是可以嵌套的,如一个方法存在事务,它调用一个方法也存在事务,如果调用的方法的事务是REQUIRED时,调用的方法不会新建事务,而是使用老的事务;如果调用方法的事务是REQUIRESNEW时,调用的方法会新建事务,而之前的事务会挂起,等这个方法结束再调用,不过这会导致事务不同步,即内部方法成功了,没有回滚,外部方法失败回滚了。

使用方式

@Transactional(readOnly = true, propagation= Propagation.REQUIRED)
public List<User> select(){
    return userMapper.select();
}

@Transactional(readOnly = true, propagation= Propagation.REQUIRES_NEW)
public int delete(Integer id){
    return userMapper.delete(id);
}


猜你喜欢

转载自blog.csdn.net/luo4105/article/details/78054325