一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第10天,点击查看活动详情。
Spring 的事务,可以说是 Spring AOP 的一种实现。
AOP面向切面编程,即在不修改源代码的情况下,对原有功能进行扩展,通过代理类来对具体类进行操作。
spring是一个容器,通过spring这个容器来对对象进行管理,根据配置文件来实现spring对对象的管理。
spring的事务声明有两种方式,编程式和声明式。spring主要是通过“声明式事务”的方式对事务进行管理,即在配置文件中进行声明,通过AOP将事务切面切入程序,最大的好处是大大减少了代码量。
Spring事务执行原理通过创建一个BeanFactoryTransactionAttributeSourceAdvisor,并把TransactionInterceptor注入进去,而TransactionInterceptor实现了Advice接口。而Spring Aop在Spring中会把Advisor中的Advice转换成拦截器链,然后调用。
执行流程
- 获取对应事务属性,也就是获取@Transactional注解上的属性
- 获取TransactionManager,常用的如DataSourceTransactionManager事务管理
- 在目标方法执行前获取事务信息并创建事务
- 回调执行下一个调用链
- 一旦出现异常,尝试异常处理,回滚事务
- 提交事务\
具体分析
事物操作
1.事物
事务在项目开发过程非常重要,涉及到数据的一致性的问题,不容马虎!
事务管理是企业级应用程序开发中必备技术,用来确保数据的完整性和一致性。
事务就是把一系列的动作当成一个独立的工作单元,这些动作要么全部完成,要么全部不起作用。 事物四个属性
- 1.原子性 :事务是原子性操作,由一系列动作组成,事务的原子性确保动作要么全部完成,要么完全不起 作用 -一致性 :一旦所有事务动作完成,事务就要被提交。数据和资源处于一种满足业务规则的一致性状态中
- 隔离性 :可能多个事务会同时处理相同的数据,因此每个事务都应该与其他事务隔离开来,防止数据损坏
- 持久性 :事务一旦完成,无论系统发生什么错误,结果都不会受到影响。通常情况下,事务的结果被写到持久化存储器中
2.事物操作
例:银行转账 转帐环境:Service(业务操作:创建转账方法、调用dao两个方法) Dao(数据库操作不写业务:创建两个方法:少钱方法、多钱方法)
1.创建数据库
2.创建Service,搭建Dao,完成对象创建和注入关系
:Service注入Dao,在FDao注入JdbcTemplate,在JdbcTemplate注入DataSource
- 接口类
package com.jdbc.account.service;
public interface UserDao {
//多钱
public void addMoney();
//少钱
public void reduceMoney();
}
- 实现类
package com.jdbc.account.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
@Repository
public class UserDaoImpl implements UserDao {
@Autowired
private JdbcTemplate jdbcTemplate;
//多钱
@Override
public void addMoney() {
String sql = "update t_account set money = money+? where username=?";
jdbcTemplate.update(sql,100,"zhang");
}
//少钱 l转帐给zhang 100元
@Override
public void reduceMoney() {
String sql = "update t_account set money = money-? where username=?";
jdbcTemplate.update(sql,100,"lic");
}
}
- Service
package com.jdbc.account.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserService {
//注入dao
@Autowired
private UserDao userDao;
//转账操作,业务逻辑层
public void accountMoney() {
//lic少一百
userDao.reduceMoney();
//zhang 多一百
userDao.addMoney();
}
}
测试
package com.jdbc.account.service;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class testMoney {
@Test
public void testAccount() {
ApplicationContext context = new ClassPathXmlApplicationContext("bean6.xml");
UserService userService = context.getBean("userService", UserService.class);
userService.accountMoney();
}
}
- 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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!--开启组件扫描-->
<context:component-scan base-package="com.jdbc.account"></context:component-scan>
<!--数据库连接池-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
<property name="url" value="jdbc:mysql://localhost:3306/test"/>
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="username" value="root"/>
<property name="password" value=""/>
</bean>
<!--jdbctemplate对象-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<!--注入dataSource-->
<property name="dataSource" ref="dataSource"></property>
</bean>
</beans>
3.当处理事物时出现异常
使用事物进行异常处理 将事物最好加入到JavaEE三层结构里面的Service层(业务逻辑层)
- 使用声明式事物管理 1.基于注解方式 2.基于xml配置文件方式
1.在Spring进行声明式事物管理,底层使用AOP原理
API:事物管理器:接口针对不同的框架提供不同的实现类
流程: 1.开启事物 2.进行业务操作 3.如果没有异常,进行提交结果到数据库 4.如果出现异常,进行事物回滚,结果不提交数据库