ToB企服应用市场:ToB评测及商务社交产业平台
标题:
Spring(四)-声明式事务
[打印本页]
作者:
南七星之家
时间:
2022-9-16 17:22
标题:
Spring(四)-声明式事务
Spring-04 声明式事务
1、事务的定义
事务就是由
一组逻辑上紧密关联
的
多个工作单元
(数据库操作)而合并成一个整体,这些操作
要么都执行,要么都不执行
。
2、事务的特性:ACID
1)原子性A :
原子即不可再分
,表现:一个事务涉及的多个操作在业务逻辑上缺一不可,保证
同一个事务中
的操作要不
都提交
,要不
都不提交
;
2)一致性C :数据的一致性,一个事务中,不管涉及到多少个操作,都
必须保证数据提交的正确性(一致);
即:如果在
事务数据处理
中,
有一个或者几个操作失败
,必须
回退所有的数据操作
,恢复到事务处理之前的
统一状态;
3)隔离性I :程序运行过程中,事务是
并发执行的
,要求每个
事务之间都是隔离的,互不干扰;
4)持久性D :事务
处理结束
,要将数据进行
持久操
作,即永久保存。
3、事务的分类:
1)编程式事务-使用jdbc原生的事务处理,可以将事务处理写在业务逻辑代码中,违背aop原则,不推荐;
2)声明式事务-使用事务
注解 @Transactional
,可以
声明在方法上
,也可以
声明在类上
;
**优先级**:
* <mark>声明在**类上**,会对**当前类内的所有方式生效**(所有方法都有事务处理);</mark>
* <mark>声明在**方法上**,只会**对当前方法生效**,当类上和方法上同时存在,**方法的优先级高于类**(有些方法,对声明式事务做特殊属性配置);</mark>
复制代码
4、事务的属性:
4.1 事务的传播行为:propagation属性
事务的传播行为:propagation 属性指定;
当
一个带事务的方法
被
另一个带事务的方法
调用时(事务嵌套),当前事务如何处理:
propagation = Propagation.
REQUIRED
:
默认值,
使用调用者的事务
(全程就一个事务,如果有
事务嵌套
,以
外部事务为主
);
propagation = Propagation.
REQUIRES_NEW
:
将
调用者
的
事务直接挂起
,自己
重开新的事务
处理,结束提交事务,失败回滚;(当
事务嵌套时
,内层事务,会
重新开启新事务的处理
,
不受
外部事务的管理);
4.2 事务的隔离级别:isolation属性
事务的隔离级别:isolation属性指定隔离级别,只有InnoDB支持事务,所有这里说的事务隔离级别指的是InnoDB下的事务隔离级别。
1、读未提交 :
读取其它事务未提交的数据
,了解,基本不会使用;
2、读已提交 :
oracle的默认事务隔离级别
,
同一个
事务处理中,
只能读取其它事务提交后的数据
(也就是说事务提交之前对其余事务不可见);
3、可重复读 :
mysql默认事务隔离级别
,
同一个
事务处理中,
多次读取同一数据
是都是一样的,不受其它事务影响;
4、串行化 : 可以
避免
上面
所有并发问题
,但是执
行效率最低
,
数据一致性最高
;
4.3 事务的指定回滚和不会滚
事务的指定回滚和不会滚:Spring在
默认的情况下
,是对所有的运行时异常会
执行事务回滚
1、 rollbackFor : 指定回滚异常,
只有产生了指定的异常类型
,才会回滚事务;
2、 noRollbackFor : 指定不会滚异常,
产生了指定的异常类型
,也不会回滚事务;
4.4 事务的超时时长-了解
1、timeout,指定事务出现异常,没有及时回滚,单位是秒,防止事务超时,占用资源;
4.5 事务的只读-了解
1、readOnly=false,默认,可读可写‘;
2、readOnly=true,
代表该事务处理,理论上只允许读取,不能修改
(只是通知spring,并不是一个强制选项)
目的就是:提示数据库驱动程序和数据库系统,这个事务并不包含更改数据的操作,那么JDBC驱动程序和数据库就有可能根据这种情况对该事务进行一些特定的优化,比方说不安排相应的数据库锁,以减轻事务对数据库的压力,毕竟事务也是要消耗数据库的资源的。
但是你非要在“只读事务”里面修改数据,也并非不可以,只不过对于数据一致性的保护不像“读写事务”那样保险而已。
5、 环境搭建
5.1主要 jar包
<spring.version>4.3.18.RELEASE</spring.version>
<mysql.version>5.1.47</mysql.version>
<c3p0.version>0.9.5.2</c3p0.version>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>${c3p0.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
复制代码
5.2 配置文件
<?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/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<context:component-scan base-package="com.kgc.spring"></context:component-scan>
<bean >
<property name="location" value="classpath:jdbc.properties"></property>
</bean>
<bean id="dataSource" >
<property name="driverClass" value="${driver}"></property>
<property name="jdbcUrl" value="${url}"></property>
<property name="user" value="${username}"></property>
<property name="password" value="${password}"></property>
</bean>
<bean id="jdbcTemplate" >
<property name="dataSource" ref="dataSource"></property>
</bean>
<bean id="dataSourceTransactionManager" >
<property name="dataSource" ref="dataSource"></property>
</bean>
<tx:annotation-driven transaction-manager="dataSourceTransactionManager"></tx:annotation-driven>
复制代码
6、测试
5.1 购买一辆车(没有事务嵌套)
TES 购买一辆 AudiQ5;
模拟购买一辆车,主要流程:(1,2,3 整体是一个事务)
1、据买家购买汽车编号,获取汽车详情;
2、扣汽车的库存
3、扣买家的余额
5.1.2 主要业务代码
5.1.2.1 扣用户余额业务
BuyerServiceImpl
如果买家余额不足,直接返回;
@Service
public class BuyerServiceImpl implements BuyerService {
@Autowired
private BuyerDao buyerDao;
@Override
public void subBuyerMoneyByName(String buyerName, Car car) {
// 根据买家姓名,查询买家详情
Buyer buyer = buyerDao.selectBuyerByName(buyerName);
// 判断买家余额是否充足,如果不足,不能继续扣减金额
if(buyer.getMoney() < car.getPrice()){
System.out.println(String.format("****** 买家:%s,余额不足! ------", buyerName));
return; //直接return
}
// 余额充足,执行扣减余额
int row = buyerDao.updateBuyerMoneyById(buyer.getId(), car.getPrice());
System.out.println(String.format("****** 买家:%s,余额扣减成功,影响行数:%s ------", buyerName, row));
}
}
复制代码
5.1.2.2 扣库存业务
CarsStockServiceImpl
如果库存不足,直接返回;
[code]@Servicepublic class CarsStockServiceImpl implements CarsStockService { @Autowired private CarsStockDao carsStockDao; @Override public void subCarsStockBuyId(Car car) { //根据汽车编号,插叙汽车详情 CarsStock carsStock = carsStockDao.selectCarsStockByCid(car.getId()); //判断库存是否充足,如果不足,不能购买 if(carsStock.getStock()
欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/)
Powered by Discuz! X3.4