Spring - Txn
事务的特性
ACID
- 原子性(Atomicity)
- 一致性(Consistency)
- 隔离性(Isolation)
- 持久性(Durability)
配置模式
1. 编程式事务管理
即使用TransactionTemplate
或者PlatformTransactionManager
,显示地将事务操作包裹在其中。如下:
EntityManagerFactory factory = Persistence.createEntityManagerFactory("PERSISTENCE_UNIT_NAME");
EntityManager entityManager = entityManagerFactory.createEntityManager();
Transaction transaction = entityManager.getTransaction()
try
{
transaction.begin();
someBusinessCode();
transaction.commit();
}
catch(Exception ex)
{
transaction.rollback();
throw ex;
}
2. 声明式事务管理
即使用annotations@
,标记需要进行事务操作的method
, class
, interface
(not recomended as not working in some cases)。
声明式事务管理建立在AOP之上,其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,执行完目标方法之后根据执行的情况提交或者回滚。
Step 1: Config
<!-- Transaction Manager -->
<bean id="txManager" class= "org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<tx:annotation-driven proxy-target-class="true" transaction-manager="txManager" />
Step 2: Use
public class SomeDAO {
@Transactional(propagation= Propagation.REQUIRES_NEW, isolation= Isolation.READ_COMMITTED, readOnly=false)
public void insert(JdbcTemplate jdbcTemplate) {
System.out.println("INSERT RECORDS");
for (int i =0; i<100; i++) {
System.out.println(i);
jdbcTemplate.execute(INSERT_SQL);
}
System.out.println("INSERT ERROR RECORDS");
}
}
事务的传播机制 - PROPAGATION
Spring事务传播机制:规定了事务方法发生”嵌套调用”时事务如何进行传播。 举例来说,Service_A中调用了Service_B,这时,由几种情况:
- 两者都是事务,Txn_A失败,Txn_B成功,怎么办?
- 两者都是事务,Txn_B失败,Txn_A成功,怎么办?
- Txn_A是事务,Txn_B不是事务,需要把Txn_B也加入Txn_A的事务一起执行嘛?
1
PROPAGATION_REQUIRED
(默认),如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。PROPAGATION_REQUIRES_NEW
,总是新建事务,如果当前存在事务,把当前事务挂起。PROPAGATION_NESTED
,如果当前存在事务,则在嵌套事务内执行。
2
PROPAGATION_SUPPORTS
,支持当前事务,如果当前没有事务,就以非事务方式执行。PROPAGATION_NOT_SUPPORTED
,不支持当前事务,如果当前存在事务,就把当前事务挂起,以非事务方式执行操作。
3
PROPAGATION_MANDATORY
,必须被拥有事务的业务方法调用。PROPAGATION_NEVER
,不能被拥有事务的其它业务方法调用。
参考 -> https://segmentfault.com/a/1190000020386113
事务的隔离级别 - ISOLATION
并发可能导致的问题:
- 脏读(Dirty read)
- 不可重复读(Nonrepeatable read)
- 幻读(Phantom reads)
隔离级别:
ISOLATION_DEFAULT
:使用后端数据库默认的隔离级别ISOLATION_READ_UNCOMMITTED
:允许读取尚未提交的更改。可能导致脏读、幻读或不可重复读。ISOLATION_READ_COMMITTED
:(Oracle 默认级别)允许从已经提交的并发事务读取。可防止脏读,但幻读和不可重复读仍可能会发生。ISOLATION_REPEATABLE_READ
:(MYSQL默认级别)对相同字段的多次读取的结果是一致的,除非数据被当前事务本身改变。可防止脏读和不可重复读,但幻读仍可能发生。ISOLATION_SERIALIZABLE
:完全服从ACID的隔离级别,确保不发生脏读、不可重复读和幻影读。这在所有隔离级别中也是最慢的,因为它通常是通过完全锁定当前事务所涉及的数据表来完成的。