spring事务都是基于数据库事务进行的,“一荣俱荣,一损俱损”,ACID特性:
- Atomic 原子性,所有操作全部执行成功事务才提交,否则回滚
- Consistency 一致性,数据库所处的状态和业务规则是一致的,比如:A转账给B,不管成功与否,A+B的总额是不变的。
- Isolation 隔离性,不同事务拥有各自的隔离空间,隔离级别越高一致性越好,并发性越弱。
- Durability 持久性,事务一旦提交成功,所有数据必须持久化到数据库中,中途遇到崩溃等原因,也要有补偿机制。
一致性 是最终目标,其他三个都是为达到一致性采取的措施和手段
数据并发问题:
场景 | 解释 |
---|
脏读 | A事务读到B事务尚未提交的更改数据,B事务回滚引发脏读 |
不可重复读 | A事务读取了B事务已经提交的更改数据导致两个时间点读取的余额不一样,加行级锁阻止操作中的数据发生变化 |
幻象读 | A事务读到了B事务新增的数据,加表级锁防止新增数据 |
第一类丢失更新 | A事务撤销时把已经提交的B事务的更新数据覆盖了 |
第二类丢失更新 | A事务提交时把已经提交的B事务的更新数据覆盖了 |
数据锁机制
锁(Oracle) | 介绍 |
---|
行共享锁定 | SELECT FOR UPDATE隠式或LOCK TABLE IN ROW SHARE MODE显式。不能防止其他会话获取独占性数据表锁定,允许进行多个并发的行共享和行独占锁定,还允许进行数据表的共享或者采用共享行独占锁定 |
行独占锁定 | INSERT UPDATE DELETE隠式或LOCK TABLE ROW EXCLUSIVE MODE显式。可以防止其他会话获取一个共享锁定、共享行独占锁定或独占锁定。 |
表共享锁定 | LOCK TABLE IN SHARE MODE显式获得。 |
表共享行独占锁定 | LOCK TABLE IN SHARE ROW EXCLUSIVE MODE显式获得。防止其他会话获得表共享、行独占或者表独占锁定,但允许其他行共享锁定。 |
表独占锁定 | LOCK TABLE IN EXCLUSIVE MODE显式获得。防止其他会话对该表的任何锁定。 |
事务隔离级别
隔离级别 | 脏读 | 不可重复读 | 幻象读 | 第一类丢失更新 | 第二类丢失更新 |
---|
READ_UNCOMMITED | 允许 | 允许 | 允许 | 不允许 | 允许 |
READ_COMMITED | 不允许 | 允许 | 允许 | 不允许 | 允许 |
REPEATABLE | 不允许 | 不允许 | 允许 | 不允许 | 不允许 |
SERIALIZABLE | 不允许 | 不允许 | 不允许 | 不允许 | 不允许 |
JDBC3.0引入了保存点特性,可以回滚到特定的保存点
Spring 使用 ThreadLocal 解决线程安全问题
private static ThreadLocal<Connection> connThreadLocal = new ThreadLocal<Connection>();
事务管理的关键抽象
类 | 描述 |
---|
PlatformTransactionManager | 根据TransactionDefinition提供的事务属性配置信息创建事务,并用TransationStatus描述这个激活事务的状态,提供getTransation commit rollback方法 |
TransactionDefinition | 定义了事务隔离,事务传播,事务超时,只读状态 |
TransationStatus | 获取事务运行期的状态信息,也可以间接的回滚事务,继承SavepointManager接口,createSavepoint rollbackSavepoint releaseSavepoint方法 |
事务 | 说明 |
---|
org.springframework.transaction.jta.JtaTransactionManager | 使用JPA进行持久化时,使用该事务管理器 |
org.springframework.orm.hibernate3.HibernateTransactionManager | 使用Hibernate X.0(X 可以为3 4 5)版本进行持久化时,使用该事务管理器 |
org.springframework.jdbc.datasource.DataSourceTransactionManager | 使用Spring JDBC 或 Mybatis 等基于DataSource数据源的持久化技术时,使用 该事务管理器 |
org.springframework.orm.jdo.JdoTransactionManager | 使用JDO进行持久化时 ,使用该事务管理器 |
org.springframework.transaction.jta.JtaTransactionManager | 具有多个数据源的全局事务使用该事务管理器(不管采用何种持久化技术) |
####事务同步管理器TransationSynchronizationManager
持久化技术 | 线程绑定资源获取工具 |
---|
spring JDBC mybatis | DataSourceUtils |
Hibernate | SessionFactoryUtils |
JPA | EntityManagerFactoryUtils |
JDO | PersistenceManagerFactoryUtils |
事务传播行为类型 | 说明 |
---|
PROPAGATION_REQUIRED | 如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。 |
PROPAGATION_SUPPORTS | 支持当前事务,如果当前没有事务,就以非事务方式执行。 |
PROPAGATION_MANDATORY | 使用当前的事务,如果当前没有事务,就抛出异常。 |
PROPAGATION_REQUIRES_NEW | 新建事务,如果当前存在事务,把当前事务挂起。 |
PROPAGATION_NOT_SUPPORTED | 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 |
PROPAGATION_NEVER | 以非事务方式执行,如果当前存在事务,则抛出异常。 |
PROPAGATION_NESTED | 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类 似的操作。 |