深入剖析Mysql事务和Spring事务,mongodb面试题2024

注意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开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
img

更多:Java进阶核心知识集

包含:JVM,JAVA集合,网络,JAVA多线程并发,JAVA基础,Spring原理,微服务,Zookeeper,Kafka,RabbitMQ,Hbase,MongoDB,Cassandra,设计模式,负载均衡,数据库,一致性哈希,JAVA算法,数据结构,加密算法,分布式缓存等等

image

高效学习视频

级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面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

相关推荐

  1. MYSQL事务面试记录

    2024-03-15 01:20:02       16 阅读
  2. mysql面试四(事务

    2024-03-15 01:20:02       14 阅读
  3. 深入剖析MySQL Innodb的事务实现原理

    2024-03-15 01:20:02       33 阅读
  4. 多角度剖析事务事件的区别

    2024-03-15 01:20:02       7 阅读
  5. 面试】谈谈MySQL事务

    2024-03-15 01:20:02       27 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-03-15 01:20:02       19 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-15 01:20:02       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-15 01:20:02       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-15 01:20:02       20 阅读

热门阅读

  1. virsh管理虚拟机的命令行工具

    2024-03-15 01:20:02       22 阅读
  2. 新手如何学习Kubernetes【入门篇】

    2024-03-15 01:20:02       26 阅读
  3. 模块化(理解)

    2024-03-15 01:20:02       23 阅读
  4. 深入理解 MySQL 中的 CASE 语句:从基础到实战

    2024-03-15 01:20:02       22 阅读
  5. 配置 conda为国内源

    2024-03-15 01:20:02       19 阅读
  6. git 批量clone,pull 项目

    2024-03-15 01:20:02       18 阅读
  7. python--运算符和字符串

    2024-03-15 01:20:02       22 阅读
  8. SpringBoot如何修改pom依赖的默认版本号

    2024-03-15 01:20:02       19 阅读
  9. vue3中子级页面绑定调用父级页面得自定义事件

    2024-03-15 01:20:02       19 阅读