Spring学习笔记十六

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;

1package springjdbc.tx; 2 3public interface IBookShopDao { 4    //根据isbn查找价格 5    public int findBookPriceByIsbn(String isbn); 6 7    //根据isbn更新库存-1 8    public void updateBookStock(String isbn); 9 10    //更新账号余额,balance - price 11    public void updateUserAccount(String userName, String price); 12} 13 14package springjdbc.tx; 15 16import org.springframework.beans.factory.annotation.Autowired; 17import org.springframework.jdbc.core.JdbcTemplate; 18import org.springframework.stereotype.Repository; 19 20@Repository("bookShopDao") 21public class BookShopDaoImple implements IBookShopDao { 22 23    @Autowired 24    private JdbcTemplate jdbcTemplate; 25 26    @Override 27    public int findBookPriceByIsbn(String isbn) { 28        String sql = "SELECT price FROM book WHERE isbn = ?"; 29 30        return jdbcTemplate.queryForObject(sql, Integer.class, isbn); 31    } 32 33    @Override 34    public void updateBookStock(String isbn) { 35        String sql2 = "SELECT stock FROM book_stock WHERE isbn = ?"; 36        int stock = jdbcTemplate.queryForObject(sql2, Integer.class, isbn); 37        if (stock == 0) { 38            throw new BookStockException("库存不足"); 39        } 40        //检查书的库存,如果不够抛出异常 41        String sql = "UPDATE book_stock SET stock = stock -1 WHERE isbn = ?"; 42        jdbcTemplate.update(sql,isbn); 43 44    } 45 46    @Override 47    public void updateUserAccount(String userName, String price) { 48        String sql2 = "SELECT balance FROM account WHERE username = ?"; 49        int balance  = jdbcTemplate.queryForObject(sql2, Integer.class, userName); 50        if (balance < Integer.valueOf(price)) { 51            throw new UserAccountException("余额不足"); 52        } 53        String sql = "UPDATE account SET balance = balance - ? WHERE userName = ?"; 54        jdbcTemplate.update(sql, price, userName); 55    } 56} 57 58package springjdbc.tx; 59 60public interface IBookShopService { 61    public void purchase(String userName, String isbn); 62 63} 64 65package springjdbc.tx; 66 67import org.springframework.beans.factory.annotation.Autowired; 68import org.springframework.stereotype.Service; 69 70@Service("bookShopService") 71public class BookShopServiceImpl implements IBookShopService { 72    @Autowired 73    private IBookShopDao iBookShopDao; 74 75    @Override 76    public void purchase(String userName, String isbn) { 77        //get book price 78        iBookShopDao.findBookPriceByIsbn(isbn); 79 80        //update book stock 81        iBookShopDao.updateBookStock(isbn); 82 83        //update user account 84        iBookShopDao.updateUserAccount(userName, isbn); 85 86    } 87} 88 89package springjdbc.tx; 90 91import org.junit.Test; 92import org.springframework.context.ApplicationContext; 93import org.springframework.context.support.ClassPathXmlApplicationContext; 94 95public class TestTx { 96    private ApplicationContext ctx = null; 97 98    private IBookShopDao iBookShopDao; 99    private IBookShopService bookShopService; 100    { 101        ctx = new ClassPathXmlApplicationContext("springjdbc/application.xml"); 102        iBookShopDao = ctx.getBean(IBookShopDao.class); 103        bookShopService = ctx.getBean(IBookShopService.class); 104    } 105 106    @Test 107    public void testBookShopService() { 108        bookShopService.purchase("AA", "100"); 109    } 110 111    @Test 112    public void testBookShopDaoFindPriceByIsbn() { 113        System.out.println(iBookShopDao.findBookPriceByIsbn("1001")); 114    } 115 116    @Test 117    public void testBookShopDaoUpdateBookStock() { 118 119        iBookShopDao.updateBookStock("1001"); 120    } 121 122    @Test 123    public void testBookShopDaoUserAccount() { 124        iBookShopDao.updateUserAccount("AA","1000" ); 125    } 126} 127 128<?xml version="1.0" encoding="UTF-8"?> 129<beans xmlns="http://www.springframework.org/schema/beans" 130       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 131       xmlns:context="http://www.springframework.org/schema/context" 132       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"> 133 134    <context:component-scan base-package="springjdbc"></context:component-scan> 135    <!-- import resource files --> 136    <context:property-placeholder location="classpath:springjdbc/db.properties"></context:property-placeholder> 137 138    <!-- C3P0 DataSource --> 139    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> 140        <property name="user" value="${jdbc.user}"/> 141        <property name="password" value="${jdbc.password}"/> 142        <property name="jdbcUrl" value="${jdbc.jdbcUrl}"/> 143        <property name="driverClass" value="${jdbc.driverClass}"/> 144        <property name="initialPoolSize" value="${jdbc.initPoolSize}"/> 145        <property name="maxPoolSize" value="${jdbc.maxPoolSize}"/> 146    </bean> 147 148    <!-- jdbc template --> 149    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> 150        <property name="dataSource" ref="dataSource"/> 151    </bean> 152 153    <!-- 具名参数 --> 154    <bean id="namedParameterJdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate"> 155        <constructor-arg ref="dataSource"/> 156    </bean> 157</beans>
点赞
收藏

评论区

加载中...

相关推荐

TiDB 性能竞赛 11.16

TiDB实现了快照隔离级别的分布式事务,支持悲观锁、乐观锁,同时也解决了大事务的难点。事务是数据库的基础,提供高效的、支持完整ACID的分布式事务更是分布式数据库的立足之本。事务是数据库执行的最小单元,允许用户将多个读写操作组合为一个逻辑单元。事务需要满足原子性、一致性、隔离性和持久性,也就是ACID。数据库有多种并发控制方法,乐观并发控制(

InnoDB MVCC何时创建read view

导读InnoDBMVCC是事务一启动就创建readview,还是什么时候?几个关于事务的基本概念说到事务,我们不得不先说下什么是ACID、MVCC、consistentread、readview等几个基本概念。ACIDACID是事务的原子性、一致性、隔离性、持久性4个单词的首字母

MySQL InnoDB如何保证事务特性

如果有人问你“数据库事务有哪些特性”?你可能会很快回答出原子性、一致性、隔离性、持久性即ACID特性。那么你知道InnoDB如何保证这些事务特性的吗?如果知道的话这篇文章就可以直接跳过不看啦(^.^)先说结论:redolog重做日志用来保证事务的持久性undolog回滚日志保证事务的原子性undologredo

MySQL(三,事务)

数据库事务特点ACID原子性,一致性,隔离性,永久性ACID是Atomic(原子性)Consistency(一致性)Isolation(隔离性)Durability(持久性)数据库事务说是如何实现的?1.通过预写日志方式实现的,redo和undo机制是数据库实现事务的基础2.redo日志用来在断电/数据

MySQL知识体系——事务

ACID(事务的四大特性)    四个特性中,最重要的就是一致性。由原子性,隔离性,持久性来保证。(以下描述用例:用户A、B、C分别在银行拥有500元存款)    原子性(Atomicity)        事务是一个不可分割的工作单元,事务中的操作要么全部COMMI

Spring声明式事务注解@Transactional

spring支持编程式事务管理和声明式事务管理两种方式。编程式事务管理使用TransactionTemplate或者直接使用底层的PlatformTransactionManager。对于编程式事务管理,spring推荐使用TransactionTemplate。声明式事务管理建立在AOP之上的。其本质是对方法前后进行拦截,然后在目标方法开始之前创