1.什么是事务
事务管理是企业级应用程序开发中必不可少的技术,用来确保数据的完整性和一致性。
事务就是一系列的动作,它们被当做一个单独的工作单元。这些动作要么全部完成,要不全部不起作用。
事务的四个关键属性(ACID)
原子性(atomicity):事务是一个原子操作,由一系列动作组成,事务的原子性确保动作要么全部完成要么完全不起作用。
一致性(consistency):一旦所有事务动作完成,事务就被提交。数据和资源就处于一种满足业务规则的一致性状态中。
隔离性(isolation):可能有许多事务会同时处理相同的数据,因此每个事务都应该与其他事务隔离开来,防止数据损坏。
持久性(durability):一旦事务完成,无论发生什么系统错误,它的结果都不应该受到影响,通常情况下,事务的结果被写到持久化存储器中。
2.spring它是支持事务的
(1)jdbc完成事务
public class Test {
public static void main(String[] args) throws SQLException {
Connection conn=null;
try {
Class.forName("com.mysql.cj.jdbc.Driver");
//serviceTimezone:mysql8.0以后要求必须设置时区
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/shiwu?serviceTimezone=Asia/Shanghai", "root", "root");
//手动开启事务
conn.setAutoCommit(false);
String sql1 = "update shiwu.users set money = money-100 where name='王五'";
PreparedStatement ps1 = conn.prepareStatement(sql1);
ps1.executeUpdate();
int i=10/0;
String sql2 = "update shiwu.users set money = money+100 where name='张三'";
PreparedStatement ps2 = conn.prepareStatement(sql2);
ps2.executeUpdate();
//提交事务
conn.commit();
}
catch (Exception e){
e.printStackTrace();
//事务回滚
conn.rollback();
}
}
}
jdbc完成事务非常复杂。--手动开启事务 --事务手动提交 --事务回滚。spring它本身也提供了事务支持。 ---事务的底层事务就是AOP面向切面方式。==事务切面类。
-----------------------------------------------------------------------------------------------------------------------------
(2)案例需求:
spring完成事务的管理:--默认提供了一个事务切面类。在pom文件中添加--spring-tx依赖---该依赖jar中包含事务管理类。
<properties>
<spring.version>5.2.15.RELEASE</spring.version>
</properties>
<!--spring事务管理依赖jar-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.2.15.RELEASE</version>
</dependency>
在spring配置文件中配置事务管理类。
<!--事务管理类:切面 开启事务 事务提交 事务回滚-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="datasource"/>
</bean>
<!--开启事务注解-->
<tx:annotation-driven/>
业务代码中添加事务注解。@Transactional---
dao层下的代码如下:
public interface BookShopDAO {
/**
* 根据编号查询图书价格
* @param isbn
* @return
*/
double findBookPriceByIsbn(String isbn);
/**
* 根据图书编号修改图书库存
* @param isbn
*/
void updateBookStock(String isbn);
/**
* 根据用户名修改余额
* @param username
* @param price
* 默认mybatis---arg0 arg1 arg2 param1 param2....
*/
void updateAccount(@Param("username") String username, @Param("price") double price);
/**
* 根据用户名查询余额
* @param username
* @return
*/
double findBalanceByUsername(String username);
int findStockByIsbn(String isbn);
}
service层的代码:
public interface BookShopService {
/**
* 购买图书
* @param isbn
* @param username
*/
public void purchase(String isbn,String username);
}
@Service(value = "bookShopService")
public class BookShopServiceImpl implements BookShopService {
@Autowired
private BookShopDAO bookShopDAO;
@Transactional
public void purchase(String isbn, String username) {
//1.查询isbn对应图书价格
double price = bookShopDAO.findBookPriceByIsbn(isbn);
//2. 查询账号余额
double balance = bookShopDAO.findBalanceByUsername(username);
//3. 判断余额是否大于等于图书价格--修改余额
if(balance<price){
throw new RuntimeException("余额不足");
}
bookShopDAO.updateAccount(username,price);
//4. 根据isbn查询库存
int stock = bookShopDAO.findStockByIsbn(isbn);
//5. 判断库存是否大于0--修改库存
if(stock<=0){
throw new RuntimeException("库存不足");
}
bookShopDAO.updateBookStock(isbn);
}
}
maper中的sql:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namesapce的内容必须和对应的接口路径映射-->
<mapper namespace="com.ykq.dao.BookShopDAO">
<update id="updateBookStock">
update shiwu.book_stock set stock=stock-1 where isbn=#{isbn}
</update>
<update id="updateAccount">
update shiwu.account set balance=balance-#{price} where username=#{username}
</update>
<!--isbn=000;drop table book;-->
<select id="findBookPriceByIsbn" resultType="java.lang.Double">
select price from shiwu.book where isbn=#{isbn}
</select>
<select id="findBalanceByUsername" resultType="java.lang.Double">
select balance from shiwu.account where username=#{username}
</select>
<select id="findStockByIsbn" resultType="java.lang.Integer">
select stock from shiwu.book_stock where isbn=#{isbn}
</select>
</mapper>
大家可以随意评论,我可以根据评论出一个完全版的总结,谢谢大家,共同进步!