Spring学习笔记十六

Easter79
• 阅读 516

Spring事务
ACID
原子性
一致性
隔离性
持久性

编程式/声明式
Spring事务管理抽象是PlatformTransactionManager
JDBC: DataSourceTransactionManager
JTA: JtaTransactionManager
Hibernate: HibernateTransactionManager

事务管理器以Bean形式声明在Spring IOC容器中

事务管理器

database: spring

create table book(
isbn varchar(50) primary key,
book_name varchar(50),
price int
);

create table account (
username varchar(50) primary key,
balance int,
check(balance >0 )
);

create table book_stock(
isbn varchar(50) primary key,
stock int
check(stock >0)
);

insert into book values(1001, 'java', 100);
insert into book values(1002, 'oracle', 70);
commit;

insert into account values('AA', 160);
commit;

insert into book_stock values(1001, 4);
insert into book_stock values(1002, 8);
commit;

package springjdbc.tx;

public interface IBookShopDao {
    //根据isbn查找价格
    public int findBookPriceByIsbn(String isbn);

    //根据isbn更新库存-1
    public void updateBookStock(String isbn);

    //更新账号余额,balance - price
    public void updateUserAccount(String userName, String price);
}

package springjdbc.tx;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

@Repository("bookShopDao")
public class BookShopDaoImple implements IBookShopDao {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public int findBookPriceByIsbn(String isbn) {
        String sql = "SELECT price FROM book WHERE isbn = ?";

        return jdbcTemplate.queryForObject(sql, Integer.class, isbn);
    }

    @Override
    public void updateBookStock(String isbn) {
        String sql2 = "SELECT stock FROM book_stock WHERE isbn = ?";
        int stock = jdbcTemplate.queryForObject(sql2, Integer.class, isbn);
        if (stock == 0) {
            throw new BookStockException("库存不足");
        }
        //检查书的库存,如果不够抛出异常
        String sql = "UPDATE book_stock SET stock = stock -1 WHERE isbn = ?";
        jdbcTemplate.update(sql,isbn);

    }

    @Override
    public void updateUserAccount(String userName, String price) {
        String sql2 = "SELECT balance FROM account WHERE username = ?";
        int balance  = jdbcTemplate.queryForObject(sql2, Integer.class, userName);
        if (balance < Integer.valueOf(price)) {
            throw new UserAccountException("余额不足");
        }
        String sql = "UPDATE account SET balance = balance - ? WHERE userName = ?";
        jdbcTemplate.update(sql, price, userName);
    }
}

package springjdbc.tx;

public interface IBookShopService {
    public void purchase(String userName, String isbn);

}

package springjdbc.tx;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service("bookShopService")
public class BookShopServiceImpl implements IBookShopService {
    @Autowired
    private IBookShopDao iBookShopDao;

    @Override
    public void purchase(String userName, String isbn) {
        //get book price
        iBookShopDao.findBookPriceByIsbn(isbn);

        //update book stock
        iBookShopDao.updateBookStock(isbn);

        //update user account
        iBookShopDao.updateUserAccount(userName, isbn);

    }
}

package springjdbc.tx;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestTx {
    private ApplicationContext ctx = null;

    private IBookShopDao iBookShopDao;
    private IBookShopService bookShopService;
    {
        ctx = new ClassPathXmlApplicationContext("springjdbc/application.xml");
        iBookShopDao = ctx.getBean(IBookShopDao.class);
        bookShopService = ctx.getBean(IBookShopService.class);
    }

    @Test
    public void testBookShopService() {
        bookShopService.purchase("AA", "100");
    }

    @Test
    public void testBookShopDaoFindPriceByIsbn() {
        System.out.println(iBookShopDao.findBookPriceByIsbn("1001"));
    }

    @Test
    public void testBookShopDaoUpdateBookStock() {

        iBookShopDao.updateBookStock("1001");
    }

    @Test
    public void testBookShopDaoUserAccount() {
        iBookShopDao.updateUserAccount("AA","1000" );
    }
}

<?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="springjdbc"></context:component-scan>
    <!-- import resource files -->
    <context:property-placeholder location="classpath:springjdbc/db.properties"></context:property-placeholder>

    <!-- C3P0 DataSource -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="user" value="${jdbc.user}"/>
        <property name="password" value="${jdbc.password}"/>
        <property name="jdbcUrl" value="${jdbc.jdbcUrl}"/>
        <property name="driverClass" value="${jdbc.driverClass}"/>
        <property name="initialPoolSize" value="${jdbc.initPoolSize}"/>
        <property name="maxPoolSize" value="${jdbc.maxPoolSize}"/>
    </bean>

    <!-- jdbc template -->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!-- 具名参数 -->
    <bean id="namedParameterJdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
        <constructor-arg ref="dataSource"/>
    </bean>
</beans>
点赞
收藏
评论区
推荐文章
Easter79 Easter79
2年前
TiDB 性能竞赛 11.16
TiDB实现了快照隔离级别的分布式事务,支持悲观锁、乐观锁,同时也解决了大事务的难点。事务是数据库的基础,提供高效的、支持完整ACID的分布式事务更是分布式数据库的立足之本。事务是数据库执行的最小单元,允许用户将多个读写操作组合为一个逻辑单元。事务需要满足原子性、一致性、隔离性和持久性,也就是ACID。数据库有多种并发控制方法,乐观并发控制(
Stella981 Stella981
2年前
InnoDB MVCC何时创建read view
导读InnoDBMVCC是事务一启动就创建readview,还是什么时候?几个关于事务的基本概念说到事务,我们不得不先说下什么是ACID、MVCC、consistentread、readview等几个基本概念。ACIDACID是事务的原子性、一致性、隔离性、持久性4个单词的首字母
Wesley13 Wesley13
2年前
MySQL InnoDB如何保证事务特性
如果有人问你“数据库事务有哪些特性”?你可能会很快回答出原子性、一致性、隔离性、持久性即ACID特性。那么你知道InnoDB如何保证这些事务特性的吗?如果知道的话这篇文章就可以直接跳过不看啦(^.^)先说结论:redolog重做日志用来保证事务的持久性undolog回滚日志保证事务的原子性undologredo
Wesley13 Wesley13
2年前
MySQL(三,事务)
数据库事务特点ACID原子性,一致性,隔离性,永久性ACID是Atomic(原子性)Consistency(一致性)Isolation(隔离性)Durability(持久性)数据库事务说是如何实现的?1.通过预写日志方式实现的,redo和undo机制是数据库实现事务的基础2.redo日志用来在断电/数据
Wesley13 Wesley13
2年前
MySQL知识体系——事务
ACID(事务的四大特性)    四个特性中,最重要的就是一致性。由原子性,隔离性,持久性来保证。(以下描述用例:用户A、B、C分别在银行拥有500元存款)    原子性(Atomicity)        事务是一个不可分割的工作单元,事务中的操作要么全部COMMI
Wesley13 Wesley13
2年前
Spring声明式事务注解@Transactional
spring支持编程式事务管理和声明式事务管理两种方式。编程式事务管理使用TransactionTemplate或者直接使用底层的PlatformTransactionManager。对于编程式事务管理,spring推荐使用TransactionTemplate。声明式事务管理建立在AOP之上的。其本质是对方法前后进行拦截,然后在目标方法开始之前创
Easter79 Easter79
2年前
Spring事务用法示例与实现原理
       关于事务,简单来说,就是为了保证数据完整性而存在的一种工具,其主要有四大特性:原子性,一致性,隔离性和持久性。对于Spring事务,其最终还是在数据库层面实现的,而Spring只是以一种比较优雅的方式对其进行封装支持。本文首先会通过一个简单的示例来讲解Spring事务是如何使用的,然后会讲解Spring是如何解析xml中的标签,并对事务进行支持
Wesley13 Wesley13
2年前
Spring事务管理
Spring提供了一流的事务管理。在Spring中可以支持声明式事务和编程式事务。    本章主要目标如下:     1,Spring事务    2,事务属性    3,事务管理器    4,声明式事务      1.1Spring的事务     事务管理在应用程序中起着至关重要的作用:它是一系列任务
Wesley13 Wesley13
2年前
Mysql事务,并发问题,锁机制
1、什么是事务事务是一条或多条数据库操作语句的组合,具备ACID,4个特点。原子性:要不全部成功,要不全部撤销隔离性:事务之间相互独立,互不干扰一致性:数据库正确地改变状态后,数据库的一致性约束没有被破坏持久性:事务的提交结果,将持久保存在数据库中2、事务并发会产生什么问题1)第一类丢失更新:在没有事务隔离的情况下,两个事务都同时
京东云开发者 京东云开发者
2个月前
Spring事务实现原理
1、引言spring的springtx模块提供了对事务管理支持,使用spring事务可以让我们从复杂的事务处理中得到解脱,无需要去处理获得连接、关闭连接、事务提交和回滚等这些操作。spring事务有编程式事务和声明式事务两种实现方式。编程式事务是通过编写代
Easter79
Easter79
Lv1
今生可爱与温柔,每一样都不能少。
文章
2.8k
粉丝
5
获赞
1.2k