Spring(五)、事务

一、事务

1、事务是数据库操作的基本单位,逻辑上一组操作,要么全成功,如果有一个失败所有的操作都失败!

经典业务场景:

银行转账 A转给B500元 A - 500 B + 500

2、事务四个特性(ACID):

a、原子性

b、一致性

c、隔离性

d、持久性

二、事务操作(搭建事务操作环境)

1、事务环境搭建

@Service

public class UserService {

@Autowired

private UserDao userDao;

public void accountMoney(){

// tom减少100

userDao.reduceMoney();

// jack增加100

userDao.addMoney();

}

}

public interface UserDao {

// tom转钱

int reduceMoney();

// jack收钱

int addMoney();

}

@Repository

public class UserDaoImpl implements UserDao {

@Autowired

private JdbcTemplate jdbcTemplate;

@Override

public int reduceMoney(){

String sql = "update c_account set money = money - ? where username = ?";

return jdbcTemplate.update(sql,"100","tom");

}

@Override

public int addMoney() {

String sql = "update c_account set money = money + ? where username = ?";

return jdbcTemplate.update(sql,"100","jack");

}

}

@Test

public void testAffair(){

ApplicationContext context = new ClassPathXmlApplicationContext("bean3.xml");

UserService userService = context.getBean("userService", UserService.class);

userService.accountMoney();

}

<?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/context http://www.springframework.org/schema/context/spring-context.xsd

http://www.springframework.org/schema/aop " target="_blank">http://www.springframework.org/schema/aop/spring-aop.xsd">

<!-- 开启注解扫描-->

<context:component-scan base-package="com.yinhai"/>

<!-- 数据库连接池 -->

<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">

<property name="url" value="jdbc:mysql:///company"/>

<property name="username" value="root"/>

<property name="password" value="123456"/>

<property name="driverClassName" value="com.mysql.jdbc.Driver"/>

</bean>

<!-- 配置jdbcTemplate对象 -->

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">

<!-- 注入dataSource -->

<property name="dataSource" ref="dataSource"/>

</bean>

</beans>

2、为什么引入事务

public void accountMoney(){

try {

// 1、开启事务

// 2、进行业务操作

// tom减少100

userDao.reduceMoney();

// jack增加100

userDao.addMoney();

// 3、没有发生异常,提交事务

} catch (Exception e) {

// 4、出现异常,事务回滚

}

}

3、事务操作-Spring事务管理介绍

a、一般会将事务添加到业务逻辑层

b、spring进行事务管理操作

编程式事务管理 和 声明式事务管理

c、声明式事务管理

基于注解方式 和 基于xml配置文件方式

d、在spring进行声明式事务管理,底层使用AOP原理

e、spring事务管理API

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

PlatformTransactionManager

4、Spring声明式事务管理(注解方式)

a、在spring配置文件配置事务管理器

<!-- 创建事务管理器 -->

<bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

<property name="dataSource" ref="dataSource"/>

</bean>

b、在spring配置文件,开启事务注解

在spring配置文件中引入名称空间tx

<?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/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

http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd

http://www.springframework.org/schema/tx " target="_blank">http://www.springframework.org/schema/tx/spring-tx.xsd">

开启事务注解

<!-- 开启事务注解 -->

<tx:annotation-driven transaction-manager="dataSourceTransactionManager"/>

c、在service类上面(或者类里面方法上面)添加事务注解

@Transactional,这个注解添加到类上面,也可以添加到方法上面

如果添加到类上面,类里面的所有方法都添加事务

如果添加到方法上面,只为这个方法添加事务

@Service

@Transactional

public class UserService {}

5、spring声明式事务管理参数配置 (注解方式)

a、事务传播行为 propagation

当一个事务方法被另外一个事务方法调用时候,这个事务方法如何进行

b、事务隔离级别 ioslation

1、事务有特性成为隔离性,多事务操作之间不会产生影响,不考虑隔离性产生很多问题

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

3、脏读 :一个未提交事务读取到另一个未提交事务的数据

4、不可重复读 :一个未提交事务读取到另一提交事务修改数据

5、幻读 :一个未提交事务读取到另一提交事务添加数据

解决办法:

Serializable(串行化):一个事务在执行过程中完全看不到其他事务对数据库所做的更新。

Repeatable Read(可重复读):一个事务在执行过程中可以看到其他事务已经提交的新插入的记录,但是不能看到其他事 务对已有记录的更新。

Read Commited(读已提交数据):一个事务在执行过程中可以看到其他事务已经提交的新插入的记录,而且能看到其他事 务已经提交的对已有记录的更新

Read Uncomitted(读未提交数据):一个事务在执行过程中可以拷打其他事务没有提交的新插入的记录,而且能看到其他 事务没有提交的对已有记录的更新。

c、timeout -- 超时时间

1、事务需要在一定时间内进行提交,如果不提交进行回滚

2、默认值是-1,设置时间以秒单位进行计算

d、readOnly -- 是否只读

e、rollbackFor -- 回滚

1、设置出现哪些异常进行事务回滚

f、noRollbackFor -- 不回滚

1、设置出现哪些异常不进行事务回滚

6、spring声明式事务管理参数配置 (XML方式)

a、配置文件中配置

配置事务管理器

配置通知

配置切入点和切面

<?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/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

http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd

http://www.springframework.org/schema/tx " target="_blank">http://www.springframework.org/schema/tx/spring-tx.xsd">

<!-- 开启注解扫描-->

<context:component-scan base-package="com.yinhai"/>

<!-- 数据库连接池 -->

<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">

<property name="url" value="jdbc:mysql:///company"/>

<property name="username" value="root"/>

<property name="password" value="123456"/>

<property name="driverClassName" value="com.mysql.jdbc.Driver"/>

</bean>

<!-- 配置jdbcTemplate对象 -->

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">

<!-- 注入dataSource -->

<property name="dataSource" ref="dataSource"/>

</bean>

<!-- 1.创建事务管理器 -->

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

<property name="dataSource" ref="dataSource"/>

</bean>

<!-- 2.配置通知(要加强的方法位置) -->

<tx:advice id="advice">

<!-- 配置事务参数 -->

<tx:attributes>

<!-- 指定哪种规则的方法上面加事务 -->

<tx:method name="accountMoney" propagation="REQUIRED"/>

<!--<tx:method name="account*"/>-->

</tx:attributes>

</tx:advice>

<!-- 3.配置切入点和切面 -->

<aop:config>

<!-- 配置切入点 -->

<aop:pointcut id="pc" expression="execution(* com.yinhai.spring5.service.UserService.*(..))"/>

<!-- 配置切面 -->

<aop:advisor advice-ref="advice" pointcut-ref="pc"/>

</aop:config>

</beans>

7、spring声明式事务管理 (完全注解方式)

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

@Configuration

@ComponentScan(basePackages = "com.yinhai")

@EnableTransactionManagement

public class TxConfig {

// 数据库连接池对象

@Bean

public DruidDataSource getDruidDataSource(){

DruidDataSource druidDataSource = new DruidDataSource();

druidDataSource.setUrl("jdbc:mysql:///company");

druidDataSource.setUsername("root");

druidDataSource.setPassword("123456");

druidDataSource.setDriverClassName("com.mysql.jdbc.Driver");

return druidDataSource;

}

// JdbcTemplate对象

@Bean

public JdbcTemplate getJdbcTemplate(DataSource dataSource){

JdbcTemplate jdbcTemplate = new JdbcTemplate();

jdbcTemplate.setDataSource(dataSource);

return jdbcTemplate;

}

// 事务管理器对象

@Bean

public DataSourceTransactionManager getDataSourceTransactionManager(DataSource dataSource){

DataSourceTransactionManager dstm = new DataSourceTransactionManager();

dstm.setDataSource(dataSource);

return dstm;

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

一只鸟儿

你的鼓励是我最大的动力

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

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

打赏作者

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

抵扣说明:

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

余额充值