什么是事务:
????数据库事务是指作为单个逻辑工作单元执行的一系列操作,这些操作要么一起成功,要么一起失败,是一个不可分割的工作单元。
在我们日常工作中,涉及到事务的场景非常多,一个service 中往往需要调用不同的 dao 层方法,这些方法要么同时成功要么同时失败,我们需要在service层确保这一点。
说到事务最典型的案例就是转账了:
张三要给李四转账 500块钱,这里涉及到两个操作,从张三的账户上减去500块钱,给李四的账户添加500块钱,这两个操作要么同时成功要么同时失败,如何确保他们同时成功或者同时失败呢?答案就是事务
事务有四大特性(ACID):
以上就是事务的四大特性。
Spring 作为Java 开发中的基础设施,对于事务也提供了很好的支持,总体上来说, Spring 支持两种类型的事务,声明式事务和编程式事务。
编程式事务类似于 Jdbc事务的写法,需要将事务的代码嵌入到业务逻辑中,这样代码的耦合度较高,而声明式事务通过AOP 的思想能够有效的将事务和业务逻辑代码解耦,因此在实际开发中,声明式事务得到了广泛的应用,而编程式事务则较少使用,考虑到文章内容的完整,本文对两种事务方式都会介绍。
????Spring 中对事务的支持提供了三大基础设施,我们先来了解下。
这三个核心类是 Spring 处理事务的核心类。
1.PlatformTransactionManager/TransactionManager 是事务处理的核心类,它有很多实现类
PlatformTransactionManager定义如下:
public interface PlatformTransactionManager extends TransactionManager {
TransactionStatus getTransaction(@Nullable TransactionDefinition var1) throws TransactionException;
void commit(TransactionStatus var1) throws TransactionException;
void rollback(TransactionStatus var1) throws TransactionException;
}
可以看到 PlatformTransactionManager中定义了基本的事务操作方法,这些事务操作方法都是平台无关的,具体的实现都是由不同的子类来实现的。
这就像 JDBC 一样,SUN公司制定标准,其他数据库厂商提供具体的实现。这么做的好处就是我们 Java程序员只需要掌握好这套标准即可,不用去管接口的具体实现。以 PlatformTransactionManager为例,它有众多实现,如果你使用的是 JDBC 那么可以将DataSourceTransactionManager作为事务管理器;如果你使用的是Hibernate,那么可以将HibernateTransactionManager 作为事务管理器;如果你使用的是JPA,那么可以将JpaTransactionManager 作为事务管理器。DataSourceTransactionManager、HibernateTransact ionManager 以及JpaTransactionManager 都是PlatformTransactio nManager 的具体实现,但是我们并不需要掌握这些具体实现类的用法,我们只需要掌握好PlatformTransactionManager的用法即可。 PlatformTransactionManager中主要有如下三个方法:
1.1.getTransaction()
getTransaction()是根据传入的TransactionDefinition获取一个事务对象,
TransactionDefinition 中定义了一些事务的基本规则,例如传播性、隔离级别等。
1.2.commit()
commit()方法用来提交事务。
1.3.rollback()用于回滚事务。
2.TransactionDefinition
public interface TransactionDefinition {
int PROPAGATION_REQUIRED = 0;
int PROPAGATION_SUPPORTS = 1;
int PROPAGATION_MANDATORY = 2;
int PROPAGATION_REQUIRES_NEW = 3;
int PROPAGATION_NOT_SUPPORTED = 4;
int PROPAGATION_NEVER = 5;
int PROPAGATION_NESTED = 6;
int ISOLATION_DEFAULT = -1;
int ISOLATION_READ_UNCOMMITTED = 1;
int ISOLATION_READ_COMMITTED = 2;
int ISOLATION_REPEATABLE_READ = 4;
int ISOLATION_SERIALIZABLE = 8;
int TIMEOUT_DEFAULT = -1;
default int getPropagationBehavior() {
return 0;
}
default int getIsolationLevel() {
return -1;
}
default int getTimeout() {
return -1;
}
default boolean isReadOnly() {
return false;
}
@Nullable
default String getName() {
return null;
}
static TransactionDefinition withDefaults() {
return StaticTransactionDefinition.INSTANCE;
}
}
TransactionDefinition用于描述事务的具体规则,也称为事务的属性:
TransactionDefinition类中方法:
TransactionDefinition也有诸多的实现类:
如果使用了编程式事务的话,直接使用DefaultTransactionDefinition即可。
3.TransactionStatus 方法和 extends的方法里面也有很多方法
TransactionStatus:
public interface TransactionStatus extends TransactionExecution, SavepointManager, Flushable {
boolean hasSavepoint();
void flush();
}
TransactionExecution:
public interface TransactionExecution {
boolean isNewTransaction();
void setRollbackOnly();
boolean isRollbackOnly();
boolean isCompleted();
}
SavepointManager:
public interface SavepointManager {
Object createSavepoint() throws TransactionException;
void rollbackToSavepoint(Object var1) throws TransactionException;
void releaseSavepoint(Object var1) throws TransactionException;
}
所以说TransactionStatus有这么多方法
以上就是Spring事务的三个基础。
编程式事务举个例子:
public class shiwu {
@Autowired
private DataSourceTransactionManager transactionManager;
public void excute(){
DefaultTransactionDefinition transactionDefinition= new DefaultTransactionDefinition();
//事务名称
transactionDefinition.setName("richfit");
//四大隔离级别中的一个,默认是这个
transactionDefinition.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
//传播特性
transactionDefinition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
TransactionStatus transactionStatus = transactionManager.getTransaction(transactionDefinition);
Savepoint savepoint1 = null;
Savepoint savepoint2 = null;
try {
try {
//创建事务回滚点
savepoint1 = (Savepoint)transactionStatus.createSavepoint();
//业务逻辑1处理
}catch (Exception e1){
//回滚
transactionStatus.rollbackToSavepoint(savepoint1);
}
try {
//创建事务回滚点
savepoint2 = (Savepoint)transactionStatus.createSavepoint();
//业务逻辑2处理
}catch (Exception e2){
//回滚
transactionStatus.rollbackToSavepoint(savepoint2);
}
//业务1和业务2处理完commit提交事务
transactionManager.commit(transactionStatus);
}catch (Exception ex){
}finally {
//防止有遗漏的回滚
if (!transactionStatus.isCompleted()){
transactionManager.rollback(transactionStatus);
}
}
}
}