Spring框架--事务

事务维度之四大原则

一致性、原子性(事务包含的操作要么完全失败回滚,要么完全成功)、隔离性(操作同一张表,数据库应该为每个用户开启一个事务,多个并发事务之间要相互隔离,在B事务看来,A事务是在它开启之前就已经关闭或者在它关闭以后才开启,数据库有多种隔离级别)、持久性(事务成功就是改完数据库,永远生效)。

操作数据会遇到的问题

当多个线程都开启事务操作的时候,数据库系统要进行事务隔离。如果不考虑事务隔离,会发生:

    1.脏读,B事务在处理过程中读取了A事务未提交的数据

    2. 不可重复读,B事务多次查询,得到不同的数据值。这是因为在事务查询间隔,A事务提交了数据。重要在于修改,

    3. 幻读。A事务将特定数据从1改到2,B事务又对这个表插入一条数据1,。A事务操作的user回过头来看,发现数据没有修改完全。

特性:幻读与不可重复读都是读取已经提交的数据,而脏读是未提交的数据。不可重复读是针对同一个数据项,而幻读针对的是一批数据。

事务维度之隔离级别

    1。Read uncommitted 读未提交  什么情况都不能保证

    2.  Read committed 读已提交      避免脏读

    3.  Repeatable read 可重复读       避免脏读、不可重复读

    4.  Seriablizable       串行化            都可避免

级别越高,数据库的效率性能越低。MySql默认是 Repeatable read. 

隔离级别的设置只针对当前连接有效。JDBC中,一个Connect对象相当于一次连接。    该对象设置的事务隔离级别针对该对象,与其他对象无关。


事务维度之传播行为

当B事务在开启之前,另外一个事务A已经存在,可以为B指定几种事务行为

    1.如果当前存在事务,加入;如果当前未存在事务,新创建。 required

    2.创建一个新事务;如果当前存在事务,把当前事务挂起来。support

    3. 如果当前存在事务,加入;如果当前不存在事务,以非事务的方式运行。propagation_mandatory

    4. 以非事务的方式运行;如果当前存在事务,挂起;required_new

    5. 以非事务的方式运行;如果当前存在事务,抛出异常;not_supported

    6.如果当前存在事务,新建一个事务加入当其嵌套事务。nested

    7. 方法绝对不能在事务范围内执行,如果方法在某个事务范围内执行,容器就抛异常。只有没有事务关联,才能正常执行。Never

一般使用第一种。根据业务场景不同具体分析使用。


事务回滚

     提示Spring事务管理器回滚事务的推荐方法是 在当前事务上下文抛出异常。Spring在抛出check异常时候不会事务回滚(就是在coding时候提交需要try catch),只有运行时异常会事务回滚。

    也可以指定setRollbackonly方法来指定某个事务必须回滚。

spring中的事务

  1.     Spring不直接管理事务,提供了多种事务管理器,一般有JDBC事务、Hibernate事务、JPA事务、Java原生事务。一般使用JDBC事务进行持久化。


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

        2.  启动注解模式

<tx:annotation-driven transaction-manager="transactionManager"/>

也可以采用配置模式

<tx:advice id="txAdvice" transaction-manager="transactionManager">
		<tx:attributes>
			<tx:method name="create*" propagation="REQUIRED" read-only="false" />
			<tx:method name="query*" propagation="SUPPORTS" read-only="true" />
			<tx:method name="*" propagation="SUPPORTS" read-only="true" />
		</tx:attributes>
	</tx:advice>
	<!-- 哪些类的哪些方法参与事务 -->
	<aop:config>
	<aop:advisor pointcut="execution(* com.service.tx..*.*(..)))"advice-ref="txAdvice" order="1" />
	<aop:advisor pointcut="execution(* com.eligicheck.service..*.*(..)))"advice-ref="txAdvice" order="2" />
	</aop:config>
配置模式统一管理,更适用于企业开发。

实际是调用sql.Connection来管理事务。其是通过dataSource获取到的。

        3. 注解配置事务

@Override
	@Transactional(value="",
	propagation=Propagation.REQUIRED,
	isolation=Isolation.DEFAULT,
	readOnly=false)

    可以配置在类上,也可以配置在方法上。方法上的事务会覆盖类上的事务。




猜你喜欢

转载自blog.csdn.net/Damon__Wang/article/details/80291499