spring|事务底层原理分析
2020-08-08 本文已影响0人
ajajaj
spring本身没有事务,spring事务是在数据库事务的基础上进行封装拓展,spring支持声明式事务、编程式事务两种,本文主要针对声明式事务进行讲解,本篇文章为《图灵学院》课程笔记
我们在使用事务的时候无非是以下几步
- 获取数据库连接 Connection con = DriverManager.getConnection()
- 开启事务con.setAutoCommit(true/false);
- 执行数据操作(crud)
- 提交事务/回滚事务 con.commit() / con.rollback()
- 关闭连接 conn.close()
其实spring是在框架中给我我们做了开启、提交/回滚的操作,使得业务代码和事务操作解耦。那么spring是如何实现在指定方法前后自动加上事务操作的呢;这就要扯到动态代理了
代理模式
- 解决的问题:将次要业务、主要业务解耦。,次要业务:起到辅助作用,辅助主要业务顺利实现,在项目中往往大量存在
具体例子如下:
接口
public interface UserDao {
void save();
}
接口实现、目标对象
public class UserDaoImpl implements UserDao {
@Override
public void save() {
System.out.println("数据已经保存");
}
}
代理对象
public class ProxyFactory {
private Object target;
public ProxyFactory(Object object) {
this.target = object;
}
public Object getProxyObject(){
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(),new InvocationHandler(){
/**
* @param proxy 负责监听的对象
* @param method 被拦截的业务方法
* @param args 被拦截业务方法的实参
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before do something...");
Object returnValue= method.invoke(target,args);
System.out.println("after do something...");
return returnValue;
}
});
}
}
测试方法
public static void main(String[] args) {
//目标对象
UserDao target = new UserDaoImpl();
//目标对象创建代理对像
UserDao proxy = (UserDao) new ProxyFactory(target).getProxyObject();
proxy.save();
}
输出结果
image结合着代理模式,spring事务的实现原理就容易理解了,业务逻辑就是主要业务,需要重复使用的事务就是次要业务,spring的事务就是通过动态代理在业务代码的前后增加开启、提交/回滚的操作,实现事务操作
spring事务特性如下
- 支持原有数据事务的隔离级别
- 加入事务传播特性概念,提供多个事务的合并或隔离的功能
- 提供声明式事务,让业务代码和事务分离,事务简单易用
spring事务的传播特性
imagespring事务隔离级别
隔离级别 | 脏读(Dirty Read) | 不可重复读(NonRepeatable Read) | 幻读(Phantom Read) |
---|---|---|---|
未提交读(Read uncommitted) | 可能 | 可能 | 可能 |
已提交读(Read committed) | 不可能 | 可能 | 可能 |
可重复读(Repeatable read) | 不可能 | 不可能 | 可能 |
可串行化(SERIALIZABLE) | 不可能 | 不可能 | 不可能 |
脏读 :
一个事物读取到另一事物未提交的更新数据
不可重复读 :
在同一事物中,多次读取同一数据返回的结果有所不同, 换句话说, 后续读取可以读到另一事物已提交的更新数据. 相反, “可重复读”在同一事物中多次读取数据时, 能够保证所读数据一样, 也就是后续读取不能读到另一事物已提交的更新数据。
幻读 :
查询表中一条数据如果不存在就插入一条,并发的时候却发现,里面居然有两条相同的数据。这就幻读的问题。
spring提供三个接口提供使用事务:
-
TransactionDefinition 事务定义
image -
PlatformTransactionManager 事务管理
image -
TransactionStatus 事务运行时状态
image
原文地址