注意max_trx_id并不是m_ids中的最大值,事务id是递增分配的。比方说现在有id为1,2,3这三个事务,之后id为3的事务提交了。那么一个新的读事务在生成ReadView时,m_ids就包括1和2,min_trx_id的值就是1,max_trx_id的值就是4。
有了这个ReadView,这样在访问某条记录时,只需要按照下边的步骤判断记录的某个版本是否可见:
-
如果被访问版本的trx_id属性值与ReadView中的creator_trx_id值相同,意味着当前事务在访问它自己修改过的记录,所以该版本可以被当前事务访问。
-
如果被访问版本的trx_id属性值小于ReadView中的min_trx_id值,表明生成该版本的事务在当前事务生成ReadView前已经提交,所以该版本可以被当前事务访问。
-
如果被访问版本的trx_id属性值大于ReadView中的max_trx_id值,表明生成该版本的事务在当前事务生成ReadView后才开启,所以该版本不可以被当前事务访问。
-
如果被访问版本的trx_id属性值在ReadView的min_trx_id和max_trx_id之间,那就需要判断一下trx_id属性值是不是在m_ids列表中,如果在,说明创建ReadView时生成该版本的事务还是活跃的,该版本不可以被访问;如果不在,说明创建ReadView时生成该版本的事务已经被提交,该版本可以被访问。
READ COMMITTED的实现方式
每次读取数据前都生成一个ReadView
REPEATABLE READ实现方式
在第一次读取数据时生成一个ReadView
题记:关于undo日志版本链与read view机制细节还需要探讨一下
二、Spring事务
2.1Spring 事务相关API
断点跟spring源码后在processon上画关于spring事务执行的流程图
www.processon.com/view/5eea03…
Spring 事务是在数据库事务的基础上进行封装扩展 其主要特性如下:
-
支持原有的数据库事务的隔离级别,加入了事务传播的概念
-
提供多个事务的合并或隔离的功能
-
提供声明式事务,让业务代码与事务分离,事务变得更易用 (AOP)
大致描述一下Spring 提供了事务相关接口:
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 = Connection.TRANSACTION_READ_UNCOMMITTED;
int ISOLATION_READ_COMMITTED = Connection.TRANSACTION_READ_COMMITTED;
int ISOLATION_REPEATABLE_READ = Connection.TRANSACTION_REPEATABLE_READ;
int ISOLATION_SERIALIZABLE = Connection.TRANSACTION_SERIALIZABLE;
int TIMEOUT_DEFAULT = -1;
int getPropagationBehavior();
int getIsolationLevel();
int getTimeout();
boolean isReadOnly();
String getName();
}
TransactionAttribute
事务属性,实现了对回滚规则的扩展(处理异常)
public interface TransactionAttribute extends TransactionDefinition {
String getQualifier();
boolean rollbackOn(Throwable ex);
}
PlatformTransactionManager
平台事务管理器
public interface PlatformTransactionManager {
TransactionStatus getTransaction(@Nullable TransactionDefinition definition)
throws TransactionException;
void commit(TransactionStatus status) throws TransactionException;
void rollback(TransactionStatus status) throws TransactionException;
}
TransactionStatus
事务运行时状态
public interface TransactionStatus extends SavepointManager, Flushable {
boolean isNewTransaction();
boolean hasSavepoint();
void setRollbackOnly();
boolean isRollbackOnly();
void flush();
boolean isCompleted();
}
TransactionInterceptor
事务拦截器,实现了MethodInterceptor
public class TransactionInterceptor extends TransactionAspectSupport implements MethodInterceptor, Serializable {
/**
-
创建新的TransactionInterceptor
-
需要设置事务管理器和事务属性。
*/
public TransactionInterceptor() {
}
public TransactionInterceptor(PlatformTransactionManager ptm, Properties attributes) {
setTransactionManager(ptm);
setTransactionAttributes(attributes);
}
public TransactionInterceptor(PlatformTransactionManager ptm, TransactionAttributeSource tas) {
setTransactionManager(ptm);
setTransactionAttributeSource(tas);
}
@Override
@Nullable
public Object invoke(MethodInvocation invocation) throws Throwable {
Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);
}
private void writeObject(ObjectOutputStream oos) throws IOException {
oos.defaultWriteObject();
oos.writeObject(getTransactionManagerBeanName());
oos.writeObject(getTransactionManager());
oos.writeObject(getTransactionAttributeSource());
oos.writeObject(getBeanFactory());
}
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
ois.defaultReadObject();
setTransactionManagerBeanName((String) ois.readObject());
setTransactionManager((PlatformTransactionManager) ois.readObject());
setTransactionAttributeSource((TransactionAttributeSource) ois.readObject());
setBeanFactory((BeanFactory) ois.readObject());
}
}
找事务拦截器 核心:TransactionInterceptor#invoke
TransactionAspectSupport
事务切面支持, 内部类TransactionInfo封装了事务相关属性
TransactionAspectSupport.TransactionInfo
protected final class TransactionInfo {
@Nullable
private final PlatformTransactionManager transactionManager;
@Nullable
private final TransactionAttribute transactionAttribute;
private final String joinpointIdentification;
@Nullable
private TransactionStatus transactionStatus;
@Nullable
private TransactionInfo oldTransactionInfo;
2.2编程式事务和声明式事务
编程式事务
演示代码:
public class SpringTransactionExample {
private static String url = “jdbc:mysql://127.0.0.1:3306/test”;
private static String user = “root”;
private static String password = “root”;
public static void main(String[] args) {
// 获取数据源
final DataSource ds = new DriverManagerDataSource(url, user, password);
// 编程式事务
final TransactionTemplate template = new TransactionTemplate();
// 设置事务管理器
template.setTransactionManager(new DataSourceTransactionManager(ds));
template.execute(new TransactionCallback() {
@Override
public Object doInTransaction(TransactionStatus status) {
Connection conn = DataSourceUtils.getConnection(ds);
Object savePoint = null;
try {
{
// 插入
PreparedStatement prepare = conn.
prepareStatement(
“insert INTO account (accountName,user,money) VALUES (?,?,?)”);
prepare.setString(1, “111”);
prepare.setString(2, “aaa”);
prepare.setInt(3, 10000);
prepare.executeUpdate();
}
// 设置保存点
savePoint = status.createSavepoint();
{
// 插入
PreparedStatement prepare = conn.
prepareStatement(
“insert INTO account (accountName,user,money) VALUES (?,?,?)”);
prepare.setString(1, “222”);
prepare.setString(2, “bbb”);
prepare.setInt(3, 10000);
prepare.executeUpdate();
}
{
// 更新
PreparedStatement prepare = conn.prepareStatement(
“UPDATE account SET money= money+100 where user=?”);
prepare.setString(1, “aaa”);
prepare.executeUpdate();
//int i=1/0;
}
} catch (SQLException e) {
e.printStackTrace();
} catch (Exception e) {
System.out.println(“更新失败”);
if (savePoint != null) {
status.rollbackToSavepoint(savePoint);
} else {
status.setRollbackOnly();
}
}
return null;
}
});
}
}
声明式事务
@Transactional
<tx:annotation-driven transaction-manager=“txManager”/>
事务注解配置,作用于类,方法上
| 属性名 | 说明 |
| :-- | :-- |
| name | 当在配置文件中有多个 TransactionManager , 可以用该属性指定选择哪个事务管理器。 |
小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
更多:Java进阶核心知识集
包含:JVM,JAVA集合,网络,JAVA多线程并发,JAVA基础,Spring原理,微服务,Zookeeper,Kafka,RabbitMQ,Hbase,MongoDB,Cassandra,设计模式,负载均衡,数据库,一致性哈希,JAVA算法,数据结构,加密算法,分布式缓存等等
高效学习视频
级Java工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**
因此收集整理了一份《2024年最新Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-4SU5u1ym-1710426750503)]
[外链图片转存中…(img-v4T02qpi-1710426750504)]
[外链图片转存中…(img-9bxnSGqQ-1710426750504)]
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
[外链图片转存中…(img-fkzypnIJ-1710426750505)]
更多:Java进阶核心知识集
包含:JVM,JAVA集合,网络,JAVA多线程并发,JAVA基础,Spring原理,微服务,Zookeeper,Kafka,RabbitMQ,Hbase,MongoDB,Cassandra,设计模式,负载均衡,数据库,一致性哈希,JAVA算法,数据结构,加密算法,分布式缓存等等
[外链图片转存中…(img-qFWU46dx-1710426750505)]
高效学习视频
本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录