当前位置: 首页 > news >正文

Spring框架(三)

目录

一、JDBC模板技术概述

1.1 什么是JDBC模板

二、JdbcTemplate使用实战

2.1 基础使用(手动创建对象)

2.2 使用Spring管理模板类

2.3 使用开源连接池(Druid)

三、模拟转账开发

3.1 基础实现

3.1.1 Service层

3.1.2 Dao层

3.1.3 配置文件

3.1.4 测试代码

3.2 使用JdbcDaoSupport实现

3.2.1 DAO层改进

3.2.2 配置文件

3.2.3 测试代码

四、Spring框架的事务管理

4.1 事务管理相关API

4.1.1 PlatformTransactionManager接口

4.1.2 TransactionDefinition接口

4.2 声明式事务管理

4.2.1 配置文件方式

4.2.2 配置文件+注解方式

4.2.3 纯注解方式

4.3 转账案例与事务管理

4.3.1 Service层

4.3.2 Dao层

4.3.3 测试代码

4.4 事务传播行为

4.5 事务隔离级别

总结


一、JDBC模板技术概述

1.1 什么是JDBC模板

Spring框架提供的JdbcTemplate类简化了传统JDBC开发流程,解决了以下痛点:

  • 自动管理连接资源(Connection/Statement/ResultSet)

  • 自动处理JDBC异常(将Checked异常转换为RuntimeException)

  • 提供简洁的API执行SQL语句

  • 支持事务管理

二、JdbcTemplate使用实战

2.1 基础使用(手动创建对象)

1. 环境搭建(创建 maven 工程,引入坐标依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.qcby</groupId><artifactId>springAOP03</artifactId><version>1.0-SNAPSHOT</version><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.0.2.RELEASE</version></dependency><dependency><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId><version>1.2</version></dependency><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.12</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>5.0.2.RELEASE</version></dependency><dependency><groupId>aopalliance</groupId><artifactId>aopalliance</artifactId><version>1.0</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>5.0.2.RELEASE</version></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.8.13</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.25</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>5.0.2.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-tx</artifactId><version>5.0.2.RELEASE</version></dependency><!-- 三、Druid开源的连接池 --><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.10</version></dependency></dependencies></project>

2. 测试代码

package com.qcby.demo1;import org.junit.Test;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;import java.util.List;
import java.util.Map;public class Demo1 {/*** 一、使用 new 对象方式完成*/@Testpublic void run1(){// 创建连接池对象,Spring 框架内置了连接池对象DriverManagerDataSource dataSource = new DriverManagerDataSource();// 设置 4 个参数dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");dataSource.setUrl("jdbc:mysql:///spring_db");dataSource.setUsername("root");dataSource.setPassword("12345");try {// 提供模板,创建对象JdbcTemplate template = new JdbcTemplate(dataSource);// 完成数据的增删改查//1.新增
//            template.update("insert into account values (null,?,?)","耶耶 ",1000);
//            System.out.println("添加成功!");//2.删除
//            template.update("delete from account where name = ? ","耶耶");
//            System.out.println("删除成功!");//3.更新
//            template.update("update account set money=money-? where name = ? ",100.00,"可可");
//            System.out.println("更新成功!");//4.查询List<Map<String, Object>> accounts=template.queryForList("select * from account");//遍历结果集System.out.println("\n当前账户信息:");for (Map<String, Object> account:accounts){System.out.println("ID:"+ account.get("id") +";姓名:" + account.get("name") +";余额:" + account.get("money"));}}catch (Exception e){System.out.println("操作失败!!!");e.printStackTrace();}}}

2.2 使用Spring管理模板类

1. 将数据源和模板类交给Spring容器管理

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"><!-- 使用Spring框架管理 --><!-- 二、Spring管理内置的连接池 demo1_1.java测试--><!-- 配置连接池 --><bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"><property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/><property name="url" value="jdbc:mysql:///spring_db" /><property name="username" value="root" /><property name="password" value="12345" /></bean><!--配置 jdbc 模板 --><bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"><property name="dataSource" ref="dataSource" /></bean> </beans>

2. 测试代码

package com.qcby.demo1;import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import java.util.List;
import java.util.Map;@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(value = "classpath:applicationContext_jdbc.xml")
public class Demo1_1 {@Autowiredprivate JdbcTemplate jdbcTemplate;/*** 测试的方式*/@Testpublic void run1(){try {jdbcTemplate.update("insert into account values (null,?,?)","图图",500);System.out.println("添加成功!");}catch (Exception e){e.printStackTrace();}}@Testpublic void run2(){try {jdbcTemplate.update("delete from account where name = ? ","图图");System.out.println("删除成功!");}catch (Exception e){e.printStackTrace();}}@Testpublic void run3(){try {jdbcTemplate.update("update account set money=money-? where name = ? ",100.00,"可可");System.out.println("更新成功!");}catch (Exception e){e.printStackTrace();}}@Testpublic void run4(){try {List<Map<String, Object>> accounts=jdbcTemplate.queryForList("select * from account");//遍历结果集System.out.println("\n当前账户信息:");for (Map<String, Object> account:accounts){System.out.println("ID:"+ account.get("id") +";姓名:" + account.get("name") +";余额:" + account.get("money"));}}catch (Exception e){e.printStackTrace();}}}

2.3 使用开源连接池(Druid)

1. 添加Druid依赖

<dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.10</version>
</dependency>

2. 创建jdbc.properties

jdbc.driverClassName=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql:///spring_db
jdbc.username=root
jdbc.password=12345

3. Spring配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"><!-- 三、Spring 框架管理开源的连接池  属性文件:jdbc.properties--><!-- 第一种写法 --><!-- 使用开源连接池<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/><property name="url" value="jdbc:mysql:///spring_db" /><property name="username" value="root" /><property name="password" value="12345" /></bean>--><!-- 加载属性文件<bean id="placeholderConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"><property name="location" value="classpath:jdbc.properties" /></bean>--><!-- 第二种写法:使用提供标签的方式 --><!-- 引入属性文件 --><context:property-placeholder location="classpath:jdbc.properties" /><!-- 加载属性的文件 配置Druid数据源 --><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="${jdbc.driverClassName}" /><property name="url" value="${jdbc.url}" /><property name="username" value="${jdbc.username}" /><property name="password" value="${jdbc.password}" /></bean><!-- 配置 jdbc 模板 --><bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"><!-- 注入属性,set方法 --><property name="dataSource" ref="dataSource" /></bean></beans>

4. 测试

package com.qcby.demo1;import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(value = "classpath:applicationContext_jdbc.xml")
public class Demo1_2 {@Autowiredprivate JdbcTemplate jdbcTemplate;/*** 测试的方式*/@Testpublic void run1(){jdbcTemplate.update("insert into account values (null,?,?)","熊四",800);System.out.println("新增成功!");}/*** 修改*/@Testpublic void run2(){jdbcTemplate.update("update account set name = ?,money = ? where id = ?","小凤",100,7);System.out.println("修改成功!");}/*** 删除*/@Testpublic void run3(){jdbcTemplate.update("delete from account where id = ?",9);System.out.println("删除成功!");}/*** 通过 id 查询*/@Testpublic void run4(){Account account = jdbcTemplate.queryForObject("select * from account where id = ?", new BeanMapper(), 6);System.out.println(account);}/*** 查询所有的数据*/@Testpublic void run5(){List<Account> list = jdbcTemplate.query("select * from account", new BeanMapper());for (Account account : list) {System.out.println(account);}}
}/*** 实现类,用来进行数据封装的*/
class BeanMapper implements RowMapper<Account> {/*** 是一行一行进行数据封装的* @param resultSet* @param i* @return* @throws SQLException*/public Account mapRow(ResultSet resultSet, int i) throws SQLException {Account account = new Account();account.setId(resultSet.getInt("id"));account.setName(resultSet.getString("name"));account.setMoney(resultSet.getDouble("money"));return account;}}

三、模拟转账开发

3.1 基础实现

3.1.1 Service层

package com.qcby.demo2.service;public interface AccountService {/*** 转账的方法* @param out 付款人* @param in 收款人* @param money 金额*/public void pay(String out,String in,double money);
}package com.qcby.demo2.service;import com.qcby.demo2.dao.AccountDao;public class AccountServiceImpl implements AccountService{private AccountDao accountDao;public void setAccountDao(AccountDao accountDao) {this.accountDao = accountDao;}/*** 转账方法* @param out 付款人* @param in 收款人* @param money 金额*/public void pay(String out, String in, double money) {// 调用 dao 方法accountDao.outMoney(out,money);accountDao.inMoney(in,money);}
}

3.1.2 Dao层

package com.qcby.demo2.dao;public interface AccountDao {/*** 付款* @param out* @param money*/public void outMoney(String out,double money);/*** 收款* @param in* @param money*/public void inMoney(String in,double money);}package com.qcby.demo2.dao;import org.springframework.jdbc.core.JdbcTemplate;public class AccountDaoImpl implements AccountDao{private JdbcTemplate jdbcTemplate;public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {this.jdbcTemplate = jdbcTemplate;}/*** 付款* @param out* @param money*/public void outMoney(String out, double money) {jdbcTemplate.update("update account set money = money - ? where name = ?",money,out);}/*** 收款* @param in* @param money*/public void inMoney(String in, double money) {jdbcTemplate.update("update account set money = money + ? where name = ?",money,in);}
}

3.1.3 配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"><!--第二种写法:使用提供标签的方式--><context:property-placeholder location="classpath:jdbc.properties" /><!--加载属性的文件--><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="${jdbc.driverClassName}" /><property name="url" value="${jdbc.url}" /><property name="username" value="${jdbc.username}" /><property name="password" value="${jdbc.password}" /></bean><!--配置 Jdbc 模板类--><bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"><property name="dataSource" ref="dataSource" /></bean><!--配置 service--><bean id="accountService" class="com.qcby.demo2.service.AccountServiceImpl"><property name="accountDao" ref="accountDao"/></bean><!--配置 service--><bean id="accountDao" class="com.qcby.demo2.dao.AccountDaoImpl"><property name="jdbcTemplate" ref="jdbcTemplate" /></bean></beans>

3.1.4 测试代码

package com.qcby.demo2;import com.qcby.demo2.service.AccountService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(value = "classpath:applicationContext_dao1.xml")
public class Demo2 {@Autowiredprivate AccountService accountService;/*** 测试转账的方法*/@Testpublic void testPay(){accountService.pay("熊大","熊二",100);}}

3.2 使用JdbcDaoSupport实现

3.2.1 DAO层改进

package com.qcby.demo2.dao;import org.springframework.jdbc.core.support.JdbcDaoSupport;//extends JdbcDaoSupport
public class AccountDaoImpl1 extends JdbcDaoSupport implements AccountDao{/*** 付款* @param out* @param money*/public void outMoney(String out, double money) {this.getJdbcTemplate().update("update account set money = money - ? where name = ?",money,out);}/*** 收款* @param in* @param money*/public void inMoney(String in, double money) {this.getJdbcTemplate().update("update account set money = money + ? where name = ?",money,in);}
}

3.2.2 配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"><!--第二种写法:使用提供标签的方式--><context:property-placeholder location="classpath:jdbc.properties" /><!--加载属性的文件--><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="${jdbc.driverClassName}" /><property name="url" value="${jdbc.url}" /><property name="username" value="${jdbc.username}" /><property name="password" value="${jdbc.password}" /></bean><!--配置 Jdbc 模板类<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"><property name="dataSource" ref="dataSource" /></bean>--><!--配置 service--><bean id="accountService" class="com.qcby.demo2.service.AccountServiceImpl"><property name="accountDao" ref="accountDao"/></bean><!--配置 dao<bean id="accountDao" class="com.qcby.demo2.dao.AccountDaoImpl"><property name="jdbcTemplate" ref="jdbcTemplate" /></bean>--><!-- 在accountDaoImpl中extends JdbcDaoSupport --><bean id="accountDao" class="com.qcby.demo2.dao.AccountDaoImpl1"><property name="dataSource" ref="dataSource"/></bean></beans>

3.2.3 测试代码

package com.qcby.demo2;import com.qcby.demo2.service.AccountService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(value = "classpath:applicationContext_dao2.xml")
public class Demo2_1 {@Autowiredprivate AccountService accountService;/*** 测试转账的方法*/@Testpublic void testPay(){accountService.pay("熊大","熊二",100);}
}

四、Spring框架的事务管理

4.1 事务管理相关API

4.1.1 PlatformTransactionManager接口

这是Spring事务管理的核心接口,根据不同的持久层框架有不同的实现:

  • DataSourceTransactionManager:用于JDBC

  • HibernateTransactionManager:用于Hibernate

  • JpaTransactionManager:用于JPA

4.1.2 TransactionDefinition接口

定义事务属性:

  • 事务隔离级别

  • 事务传播行为

  • 事务超时时间

  • 是否只读事务

4.2 声明式事务管理

4.2.1 配置文件方式

<!-- applicationContext_1.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsd"><!--第二种写法:使用提供标签的方式--><context:property-placeholder location="classpath:jdbc.properties" /><!--加载属性的文件--><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="${jdbc.driverClassName}" /><property name="url" value="${jdbc.url}" /><property name="username" value="${jdbc.username}" /><property name="password" value="${jdbc.password}" /></bean><!--配置平台事务管理器--><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource" /></bean><!--配置事务的通知(没有自己编写切面类,通知方法也不是自己编写,Spring框架提供的)--><tx:advice id="txAdvice" transaction-manager="transactionManager"><tx:attributes><!--对 pay 进行增强,设置隔离级别,传播行为,超时的时间--><tx:method name="pay" isolation="DEFAULT" propagation="REQUIRED" /><tx:method name="find*" read-only="true" /></tx:attributes></tx:advice><!-- 配置 AOP 的增强 --><aop:config><!-- Spring 框架提供系统通知,使用 advisor 标签 --><aop:advisor advice-ref="txAdvice" pointcut="execution(public * com.qcby.demo3.AccountServiceImpl.pay(..))" /></aop:config><!-- 配置 service --><bean id="accountService" class="com.qcby.demo3.AccountServiceImpl"><property name="accountDao" ref="accountDao"/></bean><!-- 配置 dao --><bean id="accountDao" class="com.qcby.demo3.AccountDaoImpl"><property name="dataSource" ref="dataSource" /></bean></beans>

4.2.2 配置文件+注解方式

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsd"><!--开启注解的扫描--><context:component-scan base-package="com.qcby.demo3" /><!--第二种写法:使用提供标签的方式--><context:property-placeholder location="classpath:jdbc.properties" /><!--加载属性的文件--><bean id="dataSource"class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName"value="${jdbc.driverClassName}" /><property name="url" value="${jdbc.url}" /><property name="username" value="${jdbc.username}" /><property name="password" value="${jdbc.password}" /></bean><!--配置平台事务管理器--><bean id="transactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource" /></bean><!--配置 Jdbc 模板类--><bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"><property name="dataSource" ref="dataSource" /></bean><!--开启事务注解的支持--><tx:annotation-driven transaction-manager="transactionManager" /></beans>
package com.qcby.demo3;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;@Service
@Transactional(isolation = Isolation.DEFAULT)
public class AccountServiceImpl implements AccountService{@Autowiredprivate AccountDao accountDao;/*** 转账方法* @param out 付款人* @param in 收款人* @param money 金额*/public void pay(String out, String in, double money) {// 调用 dao 方法accountDao.outMoney(out,money);// int a = 10 / 0;accountDao.inMoney(in,money);// 模拟在转账过程中发生异常//int a = 10 / 0;}
}

4.2.3 纯注解方式

package com.qcby.demo3;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;import javax.annotation.Resource;
import javax.sql.DataSource;/*** 配置类* @author Administrator*/
@Configuration
@ComponentScan(basePackages="com.qcby.demo3")
@EnableTransactionManagement // 开启事务注解
public class SpringConfig {/*** @return* @throws Exception*/@Bean(name="dataSource")public DataSource createDataSource() throws Exception{// 创建连接池对象,Spring 框架内置了连接池对象DriverManagerDataSource dataSource = new DriverManagerDataSource();// 设置 4 个参数dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");dataSource.setUrl("jdbc:mysql:///spring_db");dataSource.setUsername("root");dataSource.setPassword("12345");return dataSource;}/*** 创建模板对象* @return*/@Resource(name="dataSource") // 不仅可以作用在属性上,也可以作用方法上。@Bean(name="jdbcTemplate") // 把 JdbcTemplate 保存到 IOC容器中public JdbcTemplate createJdbcTemplate(DataSource dataSource){JdbcTemplate template = new JdbcTemplate(dataSource);return template;}/*** 创建平台事务管理器对象* @param dataSource* @return*/@Resource(name="dataSource")@Bean(name="transactionManager")public PlatformTransactionManagercreateTransactionManager(DataSource dataSource){DataSourceTransactionManager manager = new DataSourceTransactionManager(dataSource);return manager;}}

4.3 转账案例与事务管理

4.3.1 Service层

package com.qcby.demo3;public interface AccountService {public void pay(String out, String in, double money);
}package com.qcby.demo3;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;@Service
@Transactional(isolation = Isolation.DEFAULT)
public class AccountServiceImpl implements AccountService{@Autowiredprivate AccountDao accountDao;/*** 转账方法* @param out 付款人* @param in 收款人* @param money 金额*/public void pay(String out, String in, double money) {// 调用 dao 方法accountDao.outMoney(out,money);// int a = 10 / 0;accountDao.inMoney(in,money);// 模拟在转账过程中发生异常//int a = 10 / 0;}
}

4.3.2 Dao层

package com.qcby.demo3;public interface AccountDao {/*** 付款* @param out* @param money*/public void outMoney(String out, double money);/*** 收款* @param in* @param money*/public void inMoney(String in, double money);}package com.qcby.demo3;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;@Repository
public class AccountDaoImpl implements AccountDao {@Autowiredprivate JdbcTemplate jdbcTemplate;/*** 付款* @param out* @param money*/public void outMoney(String out, double money) {jdbcTemplate.update("update account set money = money - ? where name = ?",money,out);}/*** 收款* @param in* @param money*/public void inMoney(String in, double money) {jdbcTemplate.update("update account set money = money + ? where name = ?",money,in);}
}

4.3.3 测试代码

package com.qcby.demo3;import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;// 1.配置文件+注解方式
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(value = "classpath:applicationContext_2.xml")// 2.纯注解方式
//@RunWith(SpringJUnit4ClassRunner.class)
//@ContextConfiguration(classes = SpringConfig.class)public class Demo3 {@Autowiredprivate com.qcby.demo3.AccountService accountService;/*** 测试转账的方法*/@Testpublic void testPay() {try {accountService.pay("熊大", "熊二", 100);System.out.println("转账成功!!!");} catch (Exception e) {e.printStackTrace();System.out.println("转账失败,事务已回滚!");}}
}

4.4 事务传播行为

Spring定义了7种事务传播行为:

  1. ​PROPAGATION_REQUIRED​​(默认):如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。

  2. ​PROPAGATION_SUPPORTS​​:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。

  3. ​PROPAGATION_MANDATORY​​:如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。

  4. ​PROPAGATION_REQUIRES_NEW​​:创建一个新的事务,如果当前存在事务,则把当前事务挂起。

  5. ​PROPAGATION_NOT_SUPPORTED​​:以非事务方式运行,如果当前存在事务,则把当前事务挂起。

  6. ​PROPAGATION_NEVER​​:以非事务方式运行,如果当前存在事务,则抛出异常。

  7. ​PROPAGATION_NESTED​​:如果当前存在事务,则在嵌套事务内执行;如果当前没有事务,则创建一个新的事务。

4.5 事务隔离级别

Spring支持以下隔离级别:

  1. ​ISOLATION_DEFAULT​​:使用底层数据库的默认隔离级别。

  2. ​ISOLATION_READ_UNCOMMITTED​​:允许读取未提交的数据变更,可能导致脏读、幻读或不可重复读。

  3. ​ISOLATION_READ_COMMITTED​​:只能读取已提交的数据,防止脏读,但可能发生幻读和不可重复读。

  4. ​ISOLATION_REPEATABLE_READ​​:对同一字段的多次读取结果都是一致的,除非数据被当前事务修改,防止脏读和不可重复读,但可能发生幻读。

  5. ​ISOLATION_SERIALIZABLE​​:最高的隔离级别,完全服从ACID的隔离级别,确保事务串行执行,防止脏读、不可重复读和幻读。

总结

        本文详细介绍了Spring框架中JDBC模板技术的使用方法,Spring的JDBC模板技术大大简化了数据库操作代码,使开发者能够更专注于业务逻辑而非底层数据库交互细节。声明式事务管理则提供了灵活的事务控制方式,确保数据的一致性和完整性。

        在实际开发中,建议优先使用注解方式配置事务,它更简洁直观。对于复杂的事务需求,可以结合使用@Transactional的各种属性进行精细化控制。同时,合理选择事务隔离级别和传播行为,可以在保证数据安全的前提下提高系统性能。

相关文章:

Spring框架(三)

目录 一、JDBC模板技术概述 1.1 什么是JDBC模板 二、JdbcTemplate使用实战 2.1 基础使用&#xff08;手动创建对象&#xff09; 2.2 使用Spring管理模板类 2.3 使用开源连接池&#xff08;Druid&#xff09; 三、模拟转账开发 3.1 基础实现 3.1.1 Service层 3.1.2 Da…...

CS016-4-unity ecs

【37】将系统转换为任务 Converting System to Job 【Unity6】使用DOTS制作RTS游戏|17小时完整版|CodeMonkey|【37】将系统转换为任务 Converting System to Job_哔哩哔哩_bilibili a. 将普通的方法&#xff0c;转化成job。第一个是写一个partial struct xxx&#xff1b;第二…...

CMU-15445(4)——PROJECT#1-BufferPoolManager-Task#2

PROJECT#1-BufferPoolManager Task #2 - Disk Scheduler 在前一节我实现了 TASK1 并通过了测试&#xff0c;在本节中&#xff0c;我将逐步实现 TASK2。 如上图&#xff0c;Page Table&#xff08;页表&#xff09;通过哈希表实现&#xff0c;用于跟踪当前存在于内存中的页&am…...

[原创](计算机数学)(The Probability Lifesaver)(P10): 生日概率问题.

[作者] 常用网名: 猪头三 出生日期: 1981.XX.XX 企鹅交流: 643439947 个人网站: 80x86汇编小站 编程生涯: 2001年~至今[共24年] 职业生涯: 22年 开发语言: C/C++、80x86ASM、Object Pascal、Objective-C、C#、R、Python、PHP、Perl、 开发工具: Visual Studio、Delphi、XCode、…...

计算机组成原理——数据的表示

2.1数据的表示 整理自Beokayy_ 1.进制转换 十六进制与二进制的转换 一位十六进制等于四位二进制 四位二进制等于一位十六进制 0x173A4C0001 0111 0011 1010 0100 1100 十六进制与十进制的转换 十六转十&#xff1a;每一位数字乘以相应的16的幂再相加 十转十六&#xff1a…...

源码:处理文件格式和字符集的相关代码(3-3)

总入口&#xff1a;源码&#xff1a;处理文件格式和字符集的相关代码&#xff08;3-1&#xff09;-CSDN博客 目录 六、预览&#xff08;正确显示文本文件&#xff09; 6.1 总体逻辑 6.2 二进制显示 6.3 文本显示 六、预览&#xff08;正确显示文本文件&#xff09; 6.1 总…...

Spring MVC 对 JavaWeb 的优化:从核心组件到注解

Spring MVC 功能组件与注解对 JavaWeb 的优化 文章介绍&#xff1a; SpringMVC对比JavaWeb优势&#xff0c;Spring MVC 通过引入功能组件和注解&#xff0c;从多个维度对传统 JavaWeb 开发进行了优化&#xff0c;显著提升了开发效率和代码可维护性。以下是关键优化点的详细对…...

Mysql数据库详解

在cmd中选择数据库操作用 USE test_db; 相关概念 Sql是操作关系型数据库的编程语言 关系型数据库&#xff1a;建立在关系模型基础上&#xff0c;由多张相互连接的二维表组成的数据库 语法 sql语法分类 DDL-数据库操作 创建&#xff1a;CREATE DATABASE db_name;创建完整…...

R1 快开门式压力容器操作证备考练习题及答案

R1 快开门式压力容器操作证备考练习题及答案 判断题 1、快开门式压力容器的快开门应设计成有延时功能的联锁装置。&#xff08;√&#xff09; 解析&#xff1a;延时功能的联锁装置可以防止在容器内有压力时过早开启快开门&#xff0c;避免发生危险&#xff0c;保障设备和人…...

python打卡训练营Day27

作业&#xff1a; 编写一个装饰器 logger&#xff0c;在函数执行前后打印日志信息&#xff08;如函数名、参数、返回值&#xff09; logger def multiply(a, b):return a * bmultiply(2, 3) # 输出: # 开始执行函数 multiply&#xff0c;参数: (2, 3), {} # 函数 multiply …...

【RabbitMQ】消息丢失问题排查与解决

RabbitMQ 消息丢失是一个常见的问题&#xff0c;可能发生在消息的生产、传输、消费或 Broker 端等多个环节。消息丢失的常见原因及对应的解决方案&#xff1a; 一、消息丢失的常见原因 1. 生产端&#xff08;Producer&#xff09;原因 (1) 消息未持久化 原因&#xff1a;生产…...

idea 保证旧版本配置的同时,如何从低版本升到高版本

文章目录 前言idea 保证旧版本配置的同时,如何从低版本升到高版本1. 备份项目2. 下载最新的idea3. 安装安装包4. 导入idea2019旧配置5. 验证前言 如果您觉得有用的话,记得给博主点个赞,评论,收藏一键三连啊,写作不易啊^ _ ^。   而且听说点赞的人每天的运气都不会太差,…...

校园社区小程序源码解析

基于ThinkPHP、FastAdmin和UniApp开发的校园社区小程序源码&#xff0c;旨在为校园内的学生和教职员工提供一个便捷的在线交流和服务平台。 该小程序前端采用UniApp进行开发&#xff0c;具有良好的跨平台兼容性&#xff0c;可以轻松发布到iOS和Android平台。同时&#xff0c;后…...

Windows11安装rockerMq5.0+以及springboot集成rockerMq

安装jdk17&#xff0c;rockermq5.0需要jdk11&#xff0c;我这里使用jdk17 配置系统环境变量 ROCKETMQ_HOME D:\work\mmq\rocketmq-all-5.2.0-bin-release 编写启动脚本 D: cd D:\work\mmq\rocketmq-all-5.2.0-bin-release\bin start mqnamesrv.cmd start mqbroker.cmd -n 127.0…...

ros2中自定义的package查不到?

在ros2中自定义的package功能包&#xff0c;使用命令&#xff1a;ros2 pkg list无法查找到自己的功能包&#xff1f; 首先&#xff0c;利用ros2 pkg create命令创建好功能包之后要利用colcon build命令进行编译&#xff0c;编译成功之后&#xff0c;在当前路径需要运行命令&am…...

【Python CGI编程】

Python CGI&#xff08;通用网关接口&#xff09;编程是早期Web开发中实现动态网页的技术方案。以下是系统化指南&#xff0c;包含核心概念、实现步骤及安全实践&#xff1a; 一、CGI 基础概念 1. 工作原理 浏览器请求 → Web服务器&#xff08;如Apache&#xff09; → 执行…...

idea运行

各种小kips Linuxidea上传 Linux 部署流程 1、先在idea打好jar包&#xff0c;clean之后install 2、在Linux目录下&#xff0c;找到对应项目目录&#xff0c;把原来的jar包放在bak文件夹里面 3、杀死上一次jar包的pid ps -ef|grep cliaidata.jar kill pid 4、再进行上传新的jar…...

2025年渗透测试面试题总结-安恒[社招]售前工程师(题目+回答)

网络安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 安恒[社招]售前工程师 1. 自我介绍 2. 离职原因 3. 掌握的法律法规 4. 等级保护实施框架 5. 行业方…...

[ linux-系统 ] 命令行参数 | 环境变量

命令行参数 命令行参数是指用户在启动程序时通过命令行传递给程序的参数。这些参数可以用于控制程序的行为、传递输入数据或配置选项。 在 C/C 中&#xff0c;命令行参数通过 main 函数的参数传递 命令行参数列表 argc:参数的个数 argv[]&#xff1a;参数的清单 为什么要…...

Spring三级缓存的作用与原理详解

在Spring框架中&#xff0c;Bean的创建过程涉及到了三级缓存机制。这个机制主要是为了提高单例模式下bean实例化和依赖注入的效率。本文将深入探讨Spring中的三级缓存&#xff0c;以及其在bean生命周期中的重要作用。 首先&#xff0c;让我们理解什么是三级缓存。Spring中的三…...

Linux信号的保存

Linux系统中信号的保存涉及内核为每个进程维护的数据结构&#xff0c;确保信号在产生后、处理前被正确记录和管理。以下是详细的解释&#xff1a; 1. 信号的基本概念 信号&#xff08;Signal&#xff09;&#xff1a;用于通知进程发生了特定事件的异步通知机制&#xff0c;如…...

leetcode0215. 数组中的第K个最大元素-medium

1 题目&#xff1a;数组中的第K个最大元素 官方标定难度&#xff1a;中 给定整数数组 nums 和整数 k&#xff0c;请返回数组中第 k 个最大的元素。 请注意&#xff0c;你需要找的是数组排序后的第 k 个最大的元素&#xff0c;而不是第 k 个不同的元素。 你必须设计并实现时…...

C++(17):引用传参

目录 一、核心概念 二、代码示例&#xff1a;对比指针和引用 1. 指针传参的问题 2. 引用传参的改进 三、引用传参的优势 四、总结 一、核心概念 别名机制&#xff1a;引用是变量的别名&#xff0c;操作引用等同于操作原变量。 避免拷贝&#xff1a;直接操作原始变量&…...

handsome主题美化及优化:10.1.0最新版 - 1

文章目录 前言右侧导航栏主题标题居中页面两侧框架留白间距handsome 原生入站提示评论一键赞、踩、打卡时光机头像圆形logo 扫光赞赏按钮跳动鼠标点击特效复制版权提示彩色标签云及右栏数字自定义右键响应时间和访客总数全站字数统计版权提示时间流逝添加心知天气总结 前言 ha…...

基于React的高德地图api教程006:两点之间距离测量

文章目录 6、距离测量6.1 两点之间距离测量6.1.1 两点距离测量按钮6.1.2 点击地图添加点6.1.3 测量两点之间距离并画线6.2 测量过程显示两点之间预览线6.3 绘制完毕6.4 显示清除按钮6.5 代码下载6.06、距离测量 6.1 两点之间距离测量 6.1.1 两点距离测量按钮 实现代码: re…...

Java回溯算法解决非递减子序列问题(LeetCode 491)的深度解析

文章目录 问题描述错误代码分析原代码实现错误原因 修正方案与代码实现修正后的代码关键修正点 核心问题&#xff1a;为什么 used 不需要回溯&#xff1f;作用域与生命周期示例分析 总结算法设计要点复杂度分析 问题描述 给定一个整数数组 nums&#xff0c;找出并返回所有不同…...

基于PXIE 总线架构的Kintex UltraScale 系列FPGA 高性能数据预处理板卡

基于PXIE 总线架构的Kintex UltraScale 系列FPGA 高性能数据预处理板卡 一款基于3U PXIE 总线架构的高性能数据预处理FMC 载板&#xff0c;板卡具有1 个FMC&#xff08;HPC&#xff09;接口&#xff0c;1 个X8 GTH 背板互联接口&#xff0c;可以实现1 路PCIe x8。板卡采用Xili…...

[前端] wang 富文本 vue3

官方链接 https://www.npmjs.com/package/wangeditor-next/editor-for-vue <template><div style"border: 1px solid #ccc"><Toolbar style"border-bottom: 1px solid #ccc" :editor"editorRef" :defaultConfig"toolbarCo…...

【Python 操作 MySQL 数据库】

在 Python 中操作 MySQL 数据库主要通过 pymysql 或 mysql-connector-python 库实现。以下是完整的技术指南&#xff0c;包含连接管理、CRUD 操作和最佳实践&#xff1a; 一、环境准备 1. 安装驱动库 pip install pymysql # 推荐&#xff08;纯Python实现&#xff0…...

编译opencv4.11gstreamer 参考

0xC0000139: Entry Point Not Found gstreamer-1.0 如需要编译gstreamer模块需要提前安装好2个文件Index of /data/pkg/windows 下载带msvc的表示用Visual Studio编译 gif功能顺便勾上 最后 测试可能遇到的问题 把F:\gstreamer\1.0\x86_64\bin目录下的所有dll复制到exe所在位置…...

OpenCV边界填充(Border Padding)详解:原理、方法与代码实现

一、什么是边界填充&#xff1f; 边界填充&#xff08;Border Padding&#xff09;是图像处理中一项基础而重要的技术&#xff0c;它通过在图像边缘周围添加像素来解决卷积等操作导致的边界问题。当我们对图像应用滤波器或进行卷积操作时&#xff0c;图像边缘的像素无法像中心…...

Deeper and Wider Siamese Networks for Real-Time Visual Tracking

现象&#xff1a; the backbone networks used in Siamese trackers are relatively shallow, such as AlexNet , which does not fully take advantage of the capability of modern deep neural networks. direct replacement of backbones with existing powerful archite…...

保安员考试报名时,体检项目包含哪些?

保安员考试报名时的体检项目主要包括以下几类&#xff1a; 实验室检查&#xff1a;血常规、尿常规、大便常规是必检项目&#xff0c;主要用于检查血液、尿液和消化系统是否存在问题。部分地区可能还会检查肝功能、肾功能等&#xff0c;通过检测相关指标来评估肝脏和肾脏的功能状…...

基于SpringBoot的房屋租赁管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…...

MCU开发学习记录16* - 看门狗学习与实践(HAL库) - IWDG与WWDG -STM32CubeMX

名词解释&#xff1a; IWDG&#xff1a;Independent watchdog WWDG&#xff1a;Window watchdog LSE&#xff1a;​Low-Speed External Clock​ 统一文章结构&#xff08;数字后加*&#xff09;&#xff1a; 第一部分&#xff1a; 阐述外设工作原理&#xff1b;第二部分&#…...

如何解决LCMS 液质联用液相进样器定量环漏液问题

以下是解决安捷伦1260液相色谱仪为例的进样器定量环漏液问题的一些方法&#xff1a;视频操作 检查相关部件 检查定量环本身&#xff1a;观察定量环是否有破损、裂纹或变形等情况。如果发现定量环损坏&#xff0c;需及时更换。检查密封垫&#xff1a;查看进样阀的转子密封垫、计…...

【Linux】ssh命令 – 安全的远程连接服务

原创&#xff1a;厦门微思网络 SSH命令的概念 ssh命令的功能是安全地远程连接服务器主机系统&#xff0c;作为OpenSSH套件中的客户端连接工具&#xff0c;ssh命令可以让我们轻松地基于SSH加密协议进行远程主机访问&#xff0c;从而实现对远程服务器的管理工‍作。 语法 ssh 参…...

硬件中的OID是什么?SNMP如何通过OID获取信息?——用“图书馆”比喻彻底讲清底层原理-优雅草卓伊凡|小无

硬件中的OID是什么&#xff1f;SNMP如何通过OID获取信息&#xff1f;——用“图书馆”比喻彻底讲清底层原理-优雅草卓伊凡|小无 1. 终极比喻&#xff1a;OID是设备的“图书编码系统” 想象你走进一座巨型图书馆&#xff08;这个图书馆就是一台网络设备&#xff0c;比如路由器…...

java后端学习

1.Java基础 Java基础学习-CSDN博客 2.spring->springboot spring学习-&#xff1e;sprintboot-CSDN博客 3.maven Maven-CSDN博客 4mybatis -&#xff1e;mybatisplus mybatis -&#xff1e;mybatisplus-CSDN博客 5.git操作学习 git版本控制学习-CSDN博客 6.mysql …...

Python打卡 DAY 27

知识点回顾&#xff1a; 1. 装饰器的思想&#xff1a;进一步复用 2. 函数的装饰器写法 3. 注意内部函数的返回值 作业&#xff1a; 编写一个装饰器 logger&#xff0c;在函数执行前后打印日志信息&#xff08;如函数名、参数、返回值&#xff09; def logger(func):def wrap…...

2025蓝桥杯JAVA编程题练习Day8

1. 路径 题目描述 小蓝学习了最短路径之后特别高兴&#xff0c;他定义了一个特别的图&#xff0c;希望找到图 中的最短路径。 小蓝的图由 2021 个结点组成&#xff0c;依次编号 1 至 2021。 对于两个不同的结点 a, b&#xff0c;如果 a 和 b 的差的绝对值大于 21&#xff0…...

7 个正则化算法完整总结

哈喽&#xff01;我是我不是小upper&#xff5e;之前和大家聊过各类算法的优缺点&#xff0c;还有回归算法的总结&#xff0c;今天咱们来深入聊聊正则化算法&#xff01;这可是解决机器学习里 “过拟合” 难题的关键技术 —— 想象一下&#xff0c;模型就像个死记硬背的学生&am…...

lesson03-简单回归案例(理论+代码)

一、梯度下降 二、 线性方程怎么样&#xff1f; 三、有噪音吗&#xff1f; 四、让我们看一个列子 五、如何优化 启发式搜索 学习进度 六、线性回归、逻辑回归、分类 总结、 简单线性回归是一种统计方法&#xff0c;用于确定两个变量之间的关系。具体来说&#xff0c;它试图…...

Linux系统篇——文件描述符FD

&#x1f9e0; Linux 文件描述符&#xff08;File Descriptor&#xff09;详解与学习指南 一、什么是文件描述符&#xff08;fd&#xff09; 在 Linux 中&#xff0c;一切皆文件&#xff08;everything is a file&#xff09;&#xff0c;包括普通文件、目录、套接字&#xff…...

C++ Kafka客户端(cppkafka)安装与问题解决指南

一、cppkafka简介 cppkafka是一个现代C的Apache Kafka客户端库&#xff0c;它是对librdkafka的高级封装&#xff0c;旨在简化使用librdkafka的过程&#xff0c;同时保持最小的性能开销。 #mermaid-svg-qDUFSYLBf8cKkvdw {font-family:"trebuchet ms",verdana,arial,…...

MySQL的缓存策略

一、MySQL缓存方案用来解决什么 缓存用户定义的热点数据&#xff0c;用户直接从缓存获取热点数据&#xff0c;降低数据库的读写压力场景分析&#xff1a; 内存访问速度是磁盘访问速度 10 万倍&#xff08;数量级&#xff09;读的需求远远大于写的需求mysql 自身缓冲层跟业务无…...

ubuntu22.04卸载vscode

方法 1&#xff1a;通过 Snap 卸载 VSCode 如果你是通过 Snap 安装的 VSCode&#xff08;Ubuntu 22.04 默认推荐方式&#xff09;&#xff0c;按照以下步骤卸载&#xff1a; 检查是否通过 Snap 安装&#xff1a; bash snap list | grep code如果输出显示 code&#xff0c;说明…...

主流数据库排查与优化速查手册

主流数据库排查与优化速查手册&#xff08;优化版&#xff09; 一、连接失败 1.1 统一排查流程 #mermaid-svg-IIyarbd8VatJFN14 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-IIyarbd8VatJFN14 .error-icon{fill:…...

MySQL 数据库优化:InnoDB 存储引擎深度解析:架构、调优与最佳实践

InnoDB 是 MySQL 的默认存储引擎,因其支持事务、行级锁和崩溃恢复等特性,广泛应用于高并发、数据一致性要求高的场景。本文将从 InnoDB 的核心架构、调优策略、监控诊断、高级特性 到 备份恢复 进行系统性分析,并结合代码示例与实战案例,帮助开发者全面掌握其应用与优化技巧…...

[AI算法] LLM训练-构建transformers custom model

文章目录 1. 继承与实现基础结构2. 支持 DeepSpeed 和 Accelerate 的注意事项a. 模型输出格式b. 设备管理c. 分布式训练兼容性d. DeepSpeed 特定优化 3. 训练脚本集成建议4. 测试与调试建议 在使用 Hugging Face 的 transformers 库时&#xff0c;若要自定义一个继承自 PreTrai…...