前言
事务首先是一系列操作组成的工作单元,该工作单元内的操作是不可分割的,即要么所有操作都做,要么所有操作都不做。
事务必需满足ACID(原子性、一致性、隔离性和持久性)特性,缺一不可:
原子性(Atomicity):即事务是不可分割的最小工作单元,事务内的操作要么全做,要么全不做;
一致性(Consistency):在事务执行前数据库的数据处于正确的状态,而事务执行完成后数据库的数据还是处于正确的状态,即数据完整性约束没有被破坏。
隔离性(Isolation):并发事务执行之间无影响,在一个事务内部的操作对其他事务是不产生影响。
持久性(Durability):事务一旦执行成功,它对数据库的数据的改变必须是永久的,不会因比如遇到系统故障或断电造成数据不一致或丢失。
多个事务并发执行的问题
丢失更新:
两个事务同时更新一行数据,最后一个事务的更新会覆盖掉第一个事务的更新,从而导致第一个事务更新的数据丢失,
这是由于没有加锁造成的。
脏读:
一个事务看到了另一个事务未提交的更新数据。
不可重复读:
在同一事务中,多次读取同一数据却返回不同的结果。
幻读:
在第一个事务开始时读取到一批数据,但此后另一个事务又插入了新数据并提交,此时第一个事务又读取这批数据但发现多了一条,
即好像发生幻觉一样。
问题解决
未提交读(Read Uncommitted):
很不安全,
可能出现丢失更新、脏读、不可重复读、幻读。
提交读(Read Committed):
一个事务能读取到别的事务提交的更新数据,不能看到未提交的更新数据,
可能出现不可重复读、幻读;
可重复读(Repeatable Read):
保证同一事务中先后执行的多次查询将返回同一结果,不受其他事务影响,
可能出现幻读;
序列化(Serializable):
最高隔离级别,不允许事务并发执行,而必须串行化执行,最安全。
Spring提供的事务管理
Spring框架最核心功能之一就是事务管理:
1. 提供一致的编程式事务管理API。
2. 无侵入式的声明式事务支持。
Spring事务隔离级别
隔离级别是指若干个并发的事务之间的隔离程度。TransactionDefinition 接口中定义了五个表示隔离级别的常量:
TransactionDefinition.ISOLATION_DEFAULT:
这是默认值,表示使用底层数据库的默认隔离级别。
对大部分数据库而言,通常这值就是TransactionDefinition.ISOLATION_READ_COMMITTED。
ISOLATION_READ_UNCOMMITTED(读未提交)
ISOLATION_READ_COMMITTED(读已提交)
ISOLATION_REPEATABLE_READ(可重复读)
ISOLATION_SERIALIZABLE(串行化)
事务传播行为
事务的传播行为是指,如果在开始当前事务之前,一个事务上下文已经存在,
此时有若干选项可以指定一个事务性方法的执行行为。
在TransactionDefinition定义中包括了如下几个表示传播行为的常量:
TransactionDefinition.PROPAGATION_REQUIRED(默认):
必需有(有就不需要新建,而是加入;没有就新建)
PROPAGATION_REQUIRES_NEW:
每次创建一个新的事务(有则挂起)
PROPAGATION_SUPPORTS:
可有可无(有就不需要新建,而是加入)
PROPAGATION_NOT_SUPPORTED:
不能有(有则挂起)
PROPAGATION_NEVER:
不能用(有则异常)
PROPAGATION_MANDATORY:
必需有(有就不需要新建,而是加入;没有就异常)
PROPAGATION_NESTED:
有就嵌套,没有就新建。
内置事务管理器与编程式事务
DataSourceTransactionManager : org.springframework.jdbc.datasource
用于Spring JDBC抽象框架、iBATIS或MyBatis框架的事务管理。
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
JpaTransactionManager : org.springframework.orm.jpa
用于集成JPA实现框架时的事务管理。
<bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
声明式事务
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="save*" propagation="REQUIRED" isolation="READ_COMMITTED"/>
<tx:method name="*" propagation="REQUIRED" isolation="READ_COMMITTED" read-only="true"/>
</tx:attributes>
</tx:advice>
<tx:attributes>
<tx:method name="……"
propagation=" REQUIRED"
isolation="READ_COMMITTED"
timeout="-1"
read-only="false"
no-rollback-for=""
rollback-for=""/>
</tx:attributes>
@Transactional实现事务管理:
<tx:annotation-driven transaction-manager="txManager"/>
@Transactional(propagation=Propagation.REQUIRED, isolation=Isolation.READ_COMMITTED, readOnly=true)
事务总结