Spring事务管理

Spring事务管理

在Spring进行事务管理操作有两种方式:

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

编程式事务管理:
即通过try-catch等直接编程方式管理事务

1.开启事务 2.业务操作 3.没有异常则提交事务,有异常则回滚事务

声明式事务管理

1.基于注解方式
2.基于 xml 配置文件方式

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

**使用注解@Transactional**配置事务

Transaction参数

  • propagation:事务传播行为

多个事务直接进行调用的管理过程
在这里插入图片描述
在这里插入图片描述

  • ioslation:事务隔离级别

事务的特性称为隔离性,多个事务操作不会产生影响

三个读问题:脏读、不可重复读、虚读

  1. 脏读:一个未提交的事务读取到另一个未提交的事务的数据
  2. 不可重复读:一个未提交事务读取到另一个提交事务修改数据
  3. 虚读:一个未提交事务读取到另一提交事务添加数据

通过设置事务隔离级别解决读问题

在这里插入图片描述

  • timeout:超时时间

1.事务需要在一定时间内进行提交,如果不提交进行回滚
2.默认值是 -1 ,设置时间以秒单位进行计算

  • readOnly:是否只读

1.读:查询操作,写:添加修改删除操作
2.readOnly 默认值 false,表示可以查询,可以添加修改删除操作
3.设置 readOnly 值是 true,设置成 true 之后,只能查询

  • rollbackFor:回滚
  • noRollbackFor:不回滚

举例

以银行转账服务作为事务的例子。张三李四之间进行转账

初始账户余额
在这里插入图片描述
现,张三向李四转账100元

<!-- 组件扫描 -->
    <context:component-scan base-package="affair"></context:component-scan>

    <!-- 数据库连接池 -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
        <property name="url" value="jdbc:mysql://localhost:3306/mydatabase?serverTimezone=UTC&amp;
                  useUnicode=true&amp;characterEncoding=UTF-8&amp;useSSL=false"/>
        <property name="username" value="root"/>
        <property name="password" value="******"/>
        <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"></property>
    </bean>
public interface AccountDAO {
    public void addMoney();
    public void delMoney();
}
@Repository
public class AccountDAOImpl implements AccountDAO {
    //注入JdbcTemplate
    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public void addMoney() {
        String sql = "update bank set money=money-? where id=?";
        int update = jdbcTemplate.update(sql, 100, 1);
        System.out.println(update);
    }

    @Override
    public void delMoney() {
        String sql = "update bank set money=money+? where id=?";
        int update = jdbcTemplate.update(sql, 100, 2);
        System.out.println(update);
    }
}
@Service
public class AccountService {
    //注入dao
    @Autowired
    private AccountDAO accountDAO;

    public void accountMoney() {
        accountDAO.delMoney();
        accountDAO.addMoney();
    }
}
public class moneyTest {
    @Test
    public void test() {
        ApplicationContext context = new ClassPathXmlApplicationContext("affairs.xml");
        AccountService accountService = context.getBean("accountService", AccountService.class);
        accountService.accountMoney();
    }
}

结果:
在这里插入图片描述
如果在张三-100后抛出一个异常,那么就会出现问题:张三-100,而李四账户没有变化。

解决:

1.在xml文件中配置事务管理器并开启事务管理

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

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

2.在service文件中加入事务管理注解@Transactional
在这里插入图片描述
结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值