Spring中事务的理解
Spring中事务的理解
什么是事务?
数据库操作最基本单元,逻辑上一组操作,要么都成功,否则失败。典型场景:银行转账。
四大特性:原子、一致、隔离、持久性。ACID特性。
原子性:要么都成功,不可分割,一个失败都都失败。
一致性:操作前后总量不变。比如两人都有100块钱,一共200,一个人转给另一个人后总量还是200
隔离性:多事务操作相互不会产生影响。比如两人都去操作同一条记录,两人间互不应影响。
持久性:提交之后,表中数据真正发生变化。
事务操作(搭建操作环境,以转账为例)
示例图:
步骤:
1、创建数据库,添加记录
2、创建service和dao,完成对象创建和注入关系
service:
1 2 3 4 5 | //转账 public void account() { userDao.reduce(); userDao.addmoney(); } |
dao:
1 2 3 4 5 | public interface UserDao { public void update(); public void addmoney(); public void reduce(); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 | @Override public void addmoney() { String sql= "update count set money=money+? where username=?" ; jdbcTemplate.update(sql, 100 , "李四" ); } @Override public void reduce() { String sql= "update count set money=money-? where username=?" ; jdbcTemplate.update(sql, 100 , "张三" ); } |
3:问题:如果上述过程出现异常,会出现问题
如何用事务解决:
事务操作(Spring事务管理介绍)
1、一般添加到service层
2、在spring中进行事务管理操作
1、声明式事务管理(常用)
2、编程式事务管理
3、声明式事务管理
1、基于注解
2、基于配置文件
4、在Spring进行声明事务管理,底层使用AOP思想。
5、事务管理API
(1)、提供一个接口,代表事务管理器,这个接口提供不同框架的不同实现类
事务操作(注解式)
1、在配置文件中配置事务管理器
1 2 3 4 5 | <!--创建事务管理器--> <bean id= "transactionManager" class = "org.springframework.jdbc.datasource.DataSourceTransactionManager" > <!--注入数据源--> <property name= "dataSource" ref= "dataSource" ></property> </bean> |
2、开启事务注解
1、配置文件中引入tx命名空间
2、开启事务注解
1 2 | <!--开启事务注解--> <tx:annotation-driven transaction-manager= "transactionManager" ></tx:annotation-driven> |
3、在service类或方法上加事务注解:@Transactional
事务操作(声明式事务管理参数配置)
1、
2、propagation:事务传播行为
1、多事务方法直接进行调用,这个过程中事务是如何进行管理的
3、isolation:事务隔离级别
不考虑隔离性会出现三个问题
1、脏读:一个未提交事务读取到了另一个未提交事务的数据
2、不可重复读:一个未提交事务读取到了另一个提交事务的数据
3、幻读:一个未提交事务读取到了另一个提交事务的添加数据
设置事务隔离级别:Mysql默认用的是可重复读
4、timeout:超时时间
5、readOnly:是否只读
6、rollbackFor:回滚
7、norollbackFor:不回滚
事务操作(完全注解,使用配置类)
1、创建配置类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | @Configuration @ComponentScan (basePackages = "org.zhaojianhui.Spring" ) @EnableTransactionManagement //开启事务 public class txConfig { //创建数据库连接池 @Bean public DruidDataSource getDruid(){ DruidDataSource druidDataSource= new DruidDataSource(); druidDataSource.setDriverClassName( "" ); druidDataSource.setUrl( "" ); druidDataSource.setUsername( "" ); druidDataSource.setPassword( "" ); return druidDataSource; } } |
整合日志框架
Spring5建议使用log4j2,整合如下:
1、引入依赖:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version> 2.11 . 2 </version> </dependency> <!-- https: //mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version> 2.11 . 2 </version> </dependency> <!-- https: //mvnrepository.com/artifact/org.apache.logging.log4j/log4j-slf4j-impl --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-slf4j-impl</artifactId> <version> 2.11 . 2 </version> <scope>test</scope> </dependency> <!-- https: //mvnrepository.com/artifact/org.slf4j/slf4j-api --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version> 1.7 . 30 </version> </dependency> |
2、根目录下创建log4j2.xml的配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 | <?xml version= "1.0" encoding= "UTF-8" ?> <configuration status= "INFO" > <appenders> <console name= "Console" target= "SYSTEM_OUT" > <PatternLayout pattern= "%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" /> </console> </appenders> <loggers> <root level= "info" > <appenderRef ref= "Console" /> </root> </loggers> </configuration> |
@Nullable注解
1、可以使用在方法、属性、参数上面,表示方法返回可以为空、属性值可以为空、参数值可以为空。
2、
Spring5整合Junit4
1、引入依赖
1 2 3 4 5 | <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version> 5.2 . 0 .RELEASE</version> </dependency> |
2、创建测试类,使用注解方式完成
@RunWith(SpringJUnit4ClassRunner.class)//单元测试框架 @ContextConfiguration("classpath:bean2.xml")//加载配置文件 public class Test4 { @Autowired private UserService userService; @Test public void test1() { userService.account(); } }
Spring5整合Junit5
@ExtendWith(SpringExtension.class)
@ContextConfiguration("classpath:bean2.xml")//加载配置文件
//@SpringJUnitConfig(locations = "classpath:bean2.xml") 上面的一种简化
public class Test4 {
@Autowired
private UserService userService;
@Test
public void test1() {
userService.account();
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端