什么是事务?
事务是逻辑上的一组操作,要么都执行,要么都不执行
事务的特性(ACID)
- 原子性:事务是最小的执行单位,不允许分割,事务的原子性确保动作要么全部完成,要么全部不起作用
- 一致性: 执行事务前后,数据保持一致
- 隔离性: 并发访问数据库时,一个用户的事务不被其他事务干扰,各并发事务之间数据库都是隔离的。
- 持久性:一个事务被提交之后,它对数据库中的数据改变是持久的,即使数据库发生故障也不会对其有任何影响。
Spring事务管理接口
Spring事务管理接口
PlatformTransactionManager: 事务管理器
Spring不直接管理事务,而是提供了多种事务管理器它们将事务管理的职责委托给Hibernate、JPA等持久化机制所提供的相关平台事务来实现
常见的HibernateTransactionManager、JpaTransactionManager
TransactionDefinition: 事务定义信息
事务管理器接口PlatformTransactionManager通过getTransaction方法来得到一个事务,这个方法里面的参数是TransactionDefinition类。该类定义了5个放啊,以及一些表示事务常量比如隔离级别、传播行为等等常量。
public interface TransactionDefinition { // 返回事务的传播行为 int getPropagationBehavior(); // 返回事务的隔离级别,事务管理器根据它来控制另外一个事务可以看到本事务内的哪些数据 int getIsolationLevel(); // 返回事务必须在多少秒内完成 //返回事务的名字 String getName(); int getTimeout(); // 返回是否优化为只读事务。 boolean isReadOnly(); }
- 事务隔离级别
- 并发事务带来的问题。
- 脏读: A事务对数据修改,未提交,B事务访问的时候数据还是旧数据,并且使用了该数据
- 丢失修改(Last to modify):A事务当中发生了修改,B事务也发生了修改。第一个事务内的修改结果丢失。
- 不可重复读: A事务读取数据中,B事务修改了该数据,A事务再次读取,两次数据不一致。
- 幻读: A事务读取了几行数据,B插入了几行数据,A在该事务查询的时候发现多了一些不存在的数据
- 不可重复读取和幻读的区别在于:
- 不可重读重点是修改,幻读的重点在于新增或者删除
TransactionDefinition接口定义了5个表示隔离级别的常量
- TransactionDefinition.ISOLATION_DEFAULT:使用后端数据库默认的隔离级别。Mysql默认采用的REPEATABLE_READ隔离别,ORACLE默认采用的READ_COMMITED隔离级别
- TransactionDefinition.ISOLATION_READ_UNCOMMITED:最低的隔离级别,
允许读取尚未提交的数据变更,可能会导致脏读,幻读或不可重复读
- TransactionDefinition.ISOLATION_RREAD_COMMITED:允许读取并发事务已经提交的数据,
可以组织脏读,但是幻读或不可重复读仍有可能发生
- TransactionDefinition.ISOLATION_REPEATABLE_READ:对同一字段的多次结果是一致的,除非数据是被本身事务自己修改的,
可以组织脏读和不可重复读,但幻读仍有可能发生
- TransactionDefinition.ISOLATION_SERIALIZABLE:最高隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,
该级别可以方式脏读、不可重复度以及幻读
但是严重影响程序的性能事务传播行为:
在TransactionDefiniton定义了几个传播行为
支持当前事务
- TransactionDefinition.PROPAGATION_REQUIRED:如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新事物
- TransactionDefinition.PROPAGATION_SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有,则非事务方式运行
- TransactionDefinition.PROPAGATION_MANDATORY:如果当前存在事务,则加入事务,如果当前不存在,抛出异常
不支持当前事务的情况
- TransactionDefinition.PROPAGATION_REQUIRES_NEW:创建一个新的事务,如果当前存在事务,则把当前事务挂起。
- TransactionDefinition.PROPAGATON_NOT_SUPPORTED:以非事务方式运行,如果当前存在事务,则把事务挂起
- TransactionDefinition.PROPAGATION_NEVER:以非事务方式运行,如果当前存在事务,则抛出异常
其他情况:
TransactionDefinition.PROPAGATION_NESTED:如果当前存在事务,则创建一个事务组为当前的嵌套事务来运行,如果当前没有事务,则该取值等价于TransactionDefinition.PROPAGATION_REQUIRED。支持当前事务,和不支持当前事务都是从EJB当中引入的,而只有PROPAGATION_NESTED是Spring特有的。内嵌事务并不是一个独立的事务,它依赖于外部事务的存在,只有通过外部事物提交。才能引起内部事务的提交。嵌套的子事务不能提交,外部的回滚也会引起内部对的事务回滚。
事务超时属性:
- 事务超时表示一个事务所允许执行的最长时间,在TransactionDefinition中以int的值来表示超时时间,单位是秒
事务只读属性
- 事务只读属性是指,对事务性资源进行只读操作或者是读写操作。在TransactionDeinition以boolean类型来表示该事务是否只读
回滚规则
- 用于声明哪些异常会回滚,而哪些不会。
TransactionStatus接口
TransactionStatus接口用来记录事务的状态,该接口定义了一组方法,用来获取或者判断事务对应的状态信息。
public interface TransactionStatus{ boolean isNewTransaction(); // 是否是新的事物 boolean hasSavepoint(); // 是否有恢复点 void setRollbackOnly(); // 设置为只回滚 boolean isRollbackOnly(); // 是否为只回滚 boolean isCompleted; // 是否已完成 }
网友评论