事务维度之四大原则
一致性、原子性(事务包含的操作要么完全失败回滚,要么完全成功)、隔离性(操作同一张表,数据库应该为每个用户开启一个事务,多个并发事务之间要相互隔离,在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中的事务
- 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)
可以配置在类上,也可以配置在方法上。方法上的事务会覆盖类上的事务。