Spring事务(transaction)
事务的四大特性(ACID)
- 原子性(Atomicity)
一个事务中所有的操作,要么全部完成,要么全部不完成。事务在执行过程中,发生错误,会被回滚(roollback)到事务开始前的状态,就像整个事务从没有执行过一样 - 一致性(Consistency)
在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设约束、触发器、联级回滚等。 - 隔离性(Isolation)
数据库允许多个并发事务同时对其数据进行读写和修改,隔离性可以防止多个事务并发执行并由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括未提交读(Read Uncommitted)、提交读(Read Committed)、可重复读(Repeatable Read)和串行化(Serizalizable) - 持久性(Durability)
事务处理结束后,对数据的修改就是永久的,即系统故障也不会丢失。
三大基础设施
PlatformTransactionManager
第一个组件:PlatformTransactionManager
源码:
public interface PlatformTransactionManager extends TransactionManager {
//核心,获取一个事务对象
TransactionStatus getTransaction(@Nullable TransactionDefinition definition)
throws TransactionException;
//事务提交
void commit(TransactionStatus status) throws TransactionException;
//事务回滚
void rollback(TransactionStatus status) throws TransactionException;
}
在IDEA中按下Ctrl+H能够看到它的继承关系。
例如:DataSourceTranscationManger
如果在Spring使用的是jdbc、或者是jdbcTemplete,做事务管理是它的实现类就是DataSourceTranscationManger。
如果用hibernate,也会提供一个HibernateTranscationManger。
如果用的是JPA,也会提供一个JPATranscationManger。
PlatformTransactionManager类似JDBC规范,各个不同的实现类,就类似各个数据库厂商对不同数据库做的不同的jdbc实现(数据库驱动)。因此只需要关注PlatformTransactionManager使用即可。
TransactionDefinition
第二个组件:TransactionDefinition(事务定义),用于描述事务的具体的规则,或者叫属性
//获取事务的传播属性,不同Service之间互相调用
default int getPropagationBehavior() {
return PROPAGATION_REQUIRED;
}
//获取事务的隔离性
default int getIsolationLevel() {
return ISOLATION_DEFAULT;
}
//获取事务超时的时间
default int getTimeout() {
return TIMEOUT_DEFAULT;
}
//是否是一个只读事务
default boolean isReadOnly() {
return false;
}
另外还有一个回滚规则需要掌握。
一共五种属性。
TransactionStatus
第三个组件:TransactionStatus
//判断当前事务是否有Savepoint
boolean hasSavepoint();
//将当前事务刷新到数据库中去
void flush();
JPA用flush()较多,mybatis较少。
编程式事务以及声明式事务
编程式事务:
事务声明写在代码中,耦合度较高
声明式事务:
利用AOP的思想,在Spring中配置,或者在XML中配置的。
编程式事务示例代码:
使用PlatformTransactionManager
@Autowired
PlatformTransactionManager platformTransactionManager;
@Test
public void TestTras(){
//1.设置默认的是事务属性
DefaultTransactionDefinition defaultTransactionDefinition = new DefaultTransactionDefinition();
//2.获取transactionStatus
TransactionStatus transactionStatus = platformTransactionManager.getTransaction(defaultTransactionDefinition);
try{
//对数据库操作的代码,省略
platformTransactionManager.commit(transactionStatus);
}catch (Exception e){
platformTransactionManager.rollback(transactionStatus);
}
}
使用TransactionTemplate ,示例代码
@Autowired
TransactionTemplate transactionTemplate;
@Test
public void TestTras2(){
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
try{
//对数据库操作的代码,省略
//正常执行则会自动提交
}catch (Exception e){
//异常回滚
status.setRollbackOnly();
e.printStackTrace();
}
}
});
}