Spring5——事务操作

事务操作

1 事务?

(1)事务是操作数据库最基本的单元,逻辑上的一组操作,要么都成功,要么有一个失败所以操作都失败

(2)事务ACID四大特性:原子性、一致性、隔离性、持久性

2 搭建事务操作环境

前提:银行转账案例,一个存钱一个取钱方法

1、创建数据库表,添加记录(id、username、money)

2、创建service,搭建dao,完成对象的创建和关系注入

service注入dao,在dao注入JdbcTemplate模板,在JdbcTemplate注入DataSource

<?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"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd

                     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!--开启组件扫描-->
<context:component-scan base-package="com.znv.spring.demo5"></context:component-scan>


<!--配置连接池-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
  <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
  <property name="url" value="jdbc:mysql://master:3306/user_db"></property>
  <property name="username" value="root"></property>
  <property name="password" value="123456"></property>
</bean>

<!--创建JDBCTemplate对象-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
  <!--注入DataSource-->
  <property name="dataSource" ref="dataSource"></property>
</bean>

</beans>
@Service
public class UserService {
//注入Dao
@Autowired
private UserDao userDao;
}
@Repository
public class UserDaoImpl implements UserDao {
@Autowired
private JdbcTemplate jdbcTemplate;
}

3、在Dao里面创建两个方法:多钱和少钱的方法,在service创建方法

@Service
public class UserService {
//注入Dao
@Autowired
private UserDao userDao;

//转账的方法
public void accountMoney() {
  //少钱
  userDao.reduceMoney();

  //多钱
  userDao.addMoney();
}
}
@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,"xiaoyoupei");
}

//取钱
@Override
public void reduceMoney() {
  String sql = "update t_account set money = money+? where username=?";
  jdbcTemplate.update(sql,100,"liyan");
}
}

4、缺点?

上述代码,在执行的时候没有任何问题,但如果产生异常?

那就需要用事务进行解决,具体操作:

  try {
      //第一步 开启事务

      //第二步 进行业务操作
      //少钱
      userDao.reduceMoney();

      //多钱
      userDao.addMoney();

      //第三步 没有发生异常,提交事务
  } catch (Exception e) {
      //第四步 出现异常,事务回滚

  }
}

3 Spring中事务管理

1、事务一般添加到Service层(业务逻辑层)

2、Spring内事务管理操作

(1)两种方式:编程式事务管理、声明式事务管理(一般选择)

3、声明式事务管理

(1)基于注解方式(一般选择)

(2)基于xml配置文件方式

4、在Spring进行声明式事务管理,底层使用AOP

5、Spring事务管理API

提供一个接口,代表事务管理器,这个接口针对不同的框架提供不同的实现类

4 声明式事务管理

4.1 注解方式

1、Spring配置文件内配置事务管理器

<!--创建事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  <!--注入数据源-->
  <property name="dataSource" ref="dataSource"></property>
</bean>

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:tx="http://www.springframework.org/schema/tx"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                     http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
                     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

(2)开启事务注解

<!--开启事务注解-->
<tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>

3、在Service类上面(获取service类里面的方法上面)添加事务注解

(1)@Transactional 可以添加到类上面,也可以添加到方法上

(2)添加类,那就所有方法都添加了事务,如果只添加方法,那就该方法添加了事务

@Service
@Transactional
public class UserService {
......
}

4.2 事务参数

1、在Service类上面添加注解@Template,在这个注解上可以配置事务相关参数[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KXWpRcMn-1632834860350)(F:/ZNV/%E7%AC%94%E8%AE%B0%E5%9B%BE%E7%89%87/spring%E8%AE%B0%E5%BD%95/%E4%BA%8B%E5%8A%A1/image-20210928193815627.png)]

2、propagation:事务传播行为 看4.2.1

3、isolation:事务隔离级别 看4.2.2

4、timeout:超时时间,事务需要在一定的时间内提交,如果不提交则回滚。默认是-1,设置时间是以秒为单位

5、readonly:是否只读,读就是查询操作,写就是添加修改删除操作,readonly默认值false,表示可以查询,也可以添加修改删除操作。设置成true后只能进行查询的操作

6、rollbackFor:回滚,设置出现哪些异常进行事务回滚

7、noRollbackFor:不回滚,设置出现哪些异常不进行事务的回滚

4.2.1 事务传播行为

多事务方法直接调用,这个过程中事务是如何进行管理的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-thlp3Enk-1632834860352)(F:/ZNV/%E7%AC%94%E8%AE%B0%E5%9B%BE%E7%89%87/spring%E8%AE%B0%E5%BD%95/%E4%BA%8B%E5%8A%A1/image-20210928195024086.png)]

前提:

@Transactional
public void add(){
	//调用update方法
	update();
}


public void update(){

}

Spring框架事务传播行为有7种,下面列举典型两种

REQUIRED:如果add方法本身就有事务,调用update方法后,update使用当前add方法里面的事务;如果add方法本身没有事务,调用update方法后,创建新事务

REQUIRED_NEW:使用add方法调用update方法,无论add是否有事务,都会创建新的事务

实现

@Transactional(propagation = Propagation.REQUIRED) 
4.2.2 事务隔离级别

(1)事务有隔离性,多事务之间操作不会产生影响,不考虑隔离性产生的问题

(2)三个读问题:脏读、不可重复读、幻读

(3)三个读的解释

脏读:一个未提交事务读取到另外一个未提交事务的数据
不可重复读:一个未提交的事务读到另外一个已提交的事务
幻读:一个未提交的事务读取到另外一个事务添加数据

(4)隔离级别

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UwdUpKKu-1632834860353)(F:/ZNV/%E7%AC%94%E8%AE%B0%E5%9B%BE%E7%89%87/spring%E8%AE%B0%E5%BD%95/%E4%BA%8B%E5%8A%A1/image-20210928203416770.png)]

(5)如何设置

@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.REPEATABLE_READ) //isolation参数

mysql默认可重复读

4.3 XML方式

1、在spring配置文件中进行配置

(1)配置事务管理器

(2)配置通知

(3)配置切入点切面

   <!--1 创建事务管理器-->
   <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
       <!--注入数据源-->
       <property name="dataSource" ref="dataSource"></property>
   </bean>

   <!--2 配置通知-->
   <tx:advice id="txadvice">
       <!--配置事务参数-->
       <tx:attributes>
           <!--指定哪种规则的方法上添加事务-->
           <tx:method name="accountMoney" propagation="REQUIRED"/>
           <!--<tx:method name="account*"/>-->
       </tx:attributes>
   </tx:advice>

   <!--3 配置切入点、切面-->
   <aop:config>
       <!--配置切入点-->
       <aop:pointcut id="pt" expression="execution(* com.znv.spring.demo6.service.UserService.*(..))"/>
       <!--配置切面-->
       <aop:advisor advice-ref="txadvice" pointcut-ref="pt"/>
   </aop:config>

4.4 完全注解方式

创建配置类,使用配置类替代xml配置文件

@Configuration
@ComponentScan(basePackages = "com.znv.spring.demo6") //开启组件扫描
@EnableTransactionManagement //开启事务
public class TxConfig {

   //创建数据库的连接池
   @Bean
   public DruidDataSource getDruidDataSource() {
       DruidDataSource dataSource = new DruidDataSource();
       dataSource.setDriverClassName("com.mysql.jdbc.Driver");
       dataSource.setUrl("jdbc:mysql://master:3306/user_db");
       dataSource.setUsername("root");
       dataSource.setPassword("123456");
       return dataSource;
   }

   //创建JDBCTemplate对象
   @Bean
   public JdbcTemplate getJdbcTemplate(DataSource dataSource) {
       //到ioc容器中根据类型找到dataSource
       JdbcTemplate jdbcTemplate = new JdbcTemplate();
       //注入dataSource
       jdbcTemplate.setDataSource(dataSource);
       return jdbcTemplate;
   }

   //创建事务管理器
   @Bean
   public DataSourceTransactionManager getDataSourceTransactionManager(DataSource dataSource) {
       DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
       dataSourceTransactionManager.setDataSource(dataSource);
       return dataSourceTransactionManager;
   }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Spring中,可以使用Spring AOP来进行事务管理。其中,事务管理器是一个重要的组件。事务管理器负责管理事务的开始、提交和回滚等操作。在Spring中,常用的事务管理器是DataSourceTransactionManager。这个事务管理器是基于JDBC的事务实现的,适用于持久层采用JDBC相关技术的情况,比如Mybatis。\[1\]\[2\] 在Spring AOP事务管理中,有两个关键的角色:事务管理员和事务协调员。事务管理员通常指的是业务层开启事务的方法,而事务协调员通常指的是数据层方法或者业务层方法。事务管理员负责发起事务,而事务协调员负责加入事务。通过这种方式,可以实现对事务的管理和控制。\[3\] 总结起来,Spring AOP事务管理是通过事务管理器来管理事务的开始、提交和回滚等操作。在整合Mybatis时,可以使用DataSourceTransactionManager作为事务管理器。同时,通过事务管理员和事务协调员的配合,可以实现对事务的管理和控制。 #### 引用[.reference_title] - *1* [Spring-AOP事务管理](https://blog.csdn.net/qq_53098203/article/details/129532966)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [Spring基础3——AOP,事务管理](https://blog.csdn.net/qq_40991313/article/details/126339270)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

友培

数据皆开源!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值