事务抽象
一致的事务模型
- JDBC/Hibernate/MyBatis
- DataSource/JTA
核心接口
- PlatformTransactionManager
- DataSourceTransactionManager
- HibernateTransactionManager
- JtaTransactionManager
- TransactionDefinition
- Propagation
- Isolation
- Timeout
- Read-Only Status
1 | public interface PlatformTransactionManager { |
Propagation
传播性 | 值 | 描述 | 备注 |
---|---|---|---|
PROPAGATION_REQUIRED | 0 | 当前事务有就用当前的,没有就用新的 | 默认 |
PROPAGATION_SUPPORTS | 1 | 事务可有可无,非必须 | |
PROPAGATION_MANDATORY | 2 | 当前一定要有事务,否则就抛异常 | |
PROPAGATION_REQUIRES_NEW | 3 | 无论是否有事务,都另起一个新的事务 | 会把旧事务挂起 |
PROPAGATION_NOT_SUPPORTED | 4 | 不支持事务,按非事务方式运行 | |
PROPAGATION_NEVER | 5 | 不支持事务,如果有事务就抛出异常 | |
PROPAGATION_NESTED | 6 | 当前有事务就在当前事务再起一个事务 | 1. 里面的事务拥有独立的属性,如回滚状态 2. 里面的事务回滚并不会影响外面的事务 |
REQUIRES_NEW / NESTED
- REQUIRES_NEW:始终启动一个事务,两个事务没有关联
- NESTED:在原事务内启动一个内嵌事务,两个事务有关联,外部事务回滚,内嵌事务也会回滚
1 | 4j |
外部事务回滚
REQUIRES_NEW:外部事务回滚,不影响内部事务提交
1 |
|
NESTED:外部事务回滚,会导致内部事务也回滚!!
1 |
|
内部事务回滚
无论内部事务的propagation为NESTED或者REQUIRES_NEW,内部事务回滚都不影响外部事务提交
1 |
|
Isolation
隔离性 | 值 | 脏读 | 不可重复读 | 幻读 | 备注 |
---|---|---|---|---|---|
ISOLATION_DEFAULT | -1 | 取决于数据库配置 | |||
ISOLATION_READ_UNCOMMITTED | 1 | Y | Y | Y | |
ISOLATION_READ_COMMITTED | 2 | Y | Y | ||
ISOLATION_REPEATABLE_READ | 4 | Y | |||
ISOLATION_SERIALIZABLE | 8 |
编程式事务
- TransactionTemplate
- TransactionCallback
- TransactionCallbackWithoutResult
- PlatformTransactionManager
- 可以传入TransactionDefinition进行定义
依赖
1 | <dependency> |
schema.sql
1 | CREATE TABLE PERSON |
data.sql
1 | INSERT INTO PERSON (ID, NAME) VALUES ('1', 'zhongmingmao'); |
ProgrammaticTransactionApplication
1 | 4j |
TransactionTemplate
1 | public class TransactionTemplate extends DefaultTransactionDefinition implements TransactionOperations, InitializingBean{ |
声明式事务
Spring的声明式事务本质上是通过AOP来增强类的功能,而AOP本质上是为类做了一个代理,实际调用的是增强后的代理类
基于注解的配置
- @EnableTransactionManagement
- proxyTargetClass
- Indicate whether subclass-based (CGLIB) proxies are to be created (true) as opposed to standard Java interface-based proxies (false).
- The default is false. Applicable only if mode() is set to AdviceMode.PROXY.
- mode
- The default is AdviceMode.PROXY.
- Please note that proxy mode allows for interception of calls through the proxy only.
- Local calls within the same class cannot get intercepted that way!!
- An Transactional annotation on such a method within a local call will be ignored since Spring’s interceptor does not even kick in for such a runtime scenario.
- For a more advanced mode of interception, consider switching this to AdviceMode.ASPECTJ.
- The default is AdviceMode.PROXY.
- order
- Indicate the ordering of the execution of the transaction advisor when multiple advices are applied at a specific joinpoint.
- The default is Ordered.LOWEST_PRECEDENCE.
- proxyTargetClass
- @Transactional
- transactionManager
- propagation
- isolation
- timeout
- readOnly
- rollbackFor/noRollbackFor
PersonService接口
由于@EnableTransactionManagement的mode默认值为PROXY,PROXY对应的是JDK动态代理(基于接口)
1 | public interface PersonService { |
PersonServiceImpl
1 |
|
DeclarativeTransactionApplication
1 | 4j |