基于注解的声明式事务

 一、事务基本概念

1、什么是事务:

逻辑上的操作,这些操作要么都成功,有一个失败,那么都失败。事务由事务开始与事务结束之间执行全部数据库操作组成

例:银行转账,A向B转账100元,A账户少100元,而B账户增加100元,钱的总量是不变的。

而如果A账户钱少了,B用户钱没有增加,总量发生改变。

事务在执行过程中发生错误,会回滚到事务开始前的状态,就好像这个事务从来没有执行过一样。

事务保证了逻辑操作的成功

2、事务的特性:

1)原子性:事务操作要么全都完成,要么全部不完成

2)一致性:事务执行前后,数据库都必须处于一致状态。例:银行转账,A向B转账100元,A账户少100元,而B账户增加100元,钱的总量是不变的。

3)隔离性:在事务操作以前,每个事务有之间的数据空间,互不影响

4)持久性:在事务执行之后,对数据库的更新必须保存下来

二、事务种类

1、编程式(个人理解为手动搭建事务 比较繁琐 有时间在写)

2、声明式事务(通过配置让框架实现功能)

1)基于注解的声明式事务
  1. 添加配置(在bean.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: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/tool
         http://www.springframework.org/schema/tool/spring-tool.xsd
         http://www.springframework.org/schema/tx
         http://www.springframework.org/schema/tx/spring-tx.xsd
">
    <!--组件扫描-->
    <context:component-scan base-package="com.it.spring6.tx"></context:component-scan>
<!--    引入外部属性文件jdbc.properties,创建数据源对象-->
<context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>

    <bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="url" value="${jdbc.url}"></property>
        <property name="driverClassName" value="${jdbc.driver}"></property>
        <property name="username" value="${jdbc.user}"></property>
        <property name="password" value="${jdbc.password}"></property>

    </bean>
    <!--    创建jdbcTemplate对象,注入数据源-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="druidDataSource"></property>
    </bean>
    <!--事务管理器-->
    <bean id="transactionManager"
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="druidDataSource"></property>
    </bean>
    <!--
        开启事务注解驱动
        通过注解@Transactonal所标识的方法或标识的类中所有的方法,都会被事务管理器管理事务
    -->
    <!--transaction-manager属性的默认值是transactionManager,如果事务管理器bean的id同名 可以省略不写transaction-manager-->
    <tx:annotation-driven transaction-manager="transactionManager"/>
</beans>

2.创建表


CREATE TABLE `t_book`(
`book_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
`book_name` VARCHAR(20) DEFAULT NULL COMMENT '图书名称',
`price` int(11) DEFAULT NULL COMMENT '价格',
`stock` int(10) unsigned DEFAULT NULL COMMENT '库存(无符号)',
PRIMARY KEY(`book_id`)
)ENGINE=INNODB AUTO_INCREMENT=3 CHARSET=utf8;

INSERT INTO`t_book`(`book_id`,`book_name`,`price`,`stock`)value(1,'活着',30,100),(2,'生死疲劳',30,100);

CREATE TABLE `t_user`(
`user_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
`username` VARCHAR(20) DEFAULT NULL COMMENT '用户名',
`balance` INT(10) UNSIGNED DEFAULT NULL COMMENT '余额(无符号)',
PRIMARY KEY(`user_id`)
)ENGINE=INNODB AUTO_INCREMENT=2 DEFAULT CHARSET=UTF8;
INSERT INTO `t_user` (`user_id`, `username`, `balance`) VALUES (1, 'admin', 50);
INSERT INTO `t_user` (`user_id`, `username`, `balance`) VALUES (2, 'sun', 500);

实现表格:

实现功能:

在数据库中显示: 

2)项目结构

 BookCotroller.java

package com.it.spring6.tx.controller;

import com.it.spring6.tx.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

@Controller
public class BookController {

    @Autowired
    private BookService bookService;

    //买书的方法:图书的id和用户id
    public void buyBook(Integer bookId,Integer userId){
        //调用service方法
        bookService.buyBook(bookId,userId);
    }
}

BookDao.java

package com.it.spring6.tx.dao;

public interface BookDao {
    //根据图书id查询图书价格
    Integer getBookPriceByBookId(Integer bookId);

    //更新图书表库存量 -1
    void updateStock(Integer bookId);

    //更新用户表用户余额 -图书价格
    void updateUserBalance(Integer bookId, Integer price);
}

BookDaoImpl.java

package com.it.spring6.tx.dao;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
//dao层数据访问层 真正访问数据库的
@Repository
public class BookDaoImpl implements BookDao{
    @Autowired
    private JdbcTemplate jdbcTemplate;
    //根据图书id查询图书的价格
    @Override
    public Integer getBookPriceByBookId(Integer bookId) {
        String sql = "select price from t_book where book_id=?";
        Integer price = jdbcTemplate.queryForObject(sql, Integer.class, bookId);
        return price;
    }

    //更新库存
    @Override
    public void updateStock(Integer bookId) {
        String sql = "update t_book set stock=stock-1 where book_id=?";
        jdbcTemplate.update(sql, bookId);

    }

    //更新用户余额 -图书价格
    @Override
    public void updateUserBalance(Integer userId, Integer price) {
        String sql = "update t_user set balance=balance-? where user_id=?";
        jdbcTemplate.update(sql,price,userId);
    }
}

BookService.java 

package com.it.spring6.tx.service;

public interface BookService {
    //买书的方法:图书的id和用户id
    void buyBook(Integer bookId, Integer userId);

}

BookServiceImpl.java //@Transactional开启事务

package com.it.spring6.tx.service;

import com.it.spring6.tx.dao.BookDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

//Service层 业务逻辑层
@Service
public class BookServiceImpl implements BookService{
    @Autowired
    private BookDao bookDao;

    //买书的方法:图书的id和用户id
    @Transactional //放在方法上 只会对当前方法起作用 放在类上会对所有方法起作用
    @Override
    public void buyBook(Integer bookId, Integer userId) {
        //根据图书id查询图书价格
        Integer price = bookDao.getBookPriceByBookId(bookId);
        //更新图书表库存量 -1
        bookDao.updateStock(bookId);
        //更新用户表用户余额 -图书价格
        bookDao.updateUserBalance(userId,price);
    }
}

 TestBook.java

package com.it.spring6.tx;

import com.it.spring6.tx.controller.BookController;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;

@SpringJUnitConfig(locations = "classpath:bean.xml")
public class TestBookTx {

    @Autowired
    private BookController bookController;

    @Test
    public  void testBuyBook(){
        bookController.buyBook(1,2);
    }
}

 运行成功

关于jdbc:

spring6实现增删改查-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值