Spring 事务控制-第5天

Spring 事务控制-第5天1.事务前提知识1.1 事务的特性原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚,没有中间停留环节。因此事务的操作如果成功就必须要完全应用到数据库,如果操作失败则不能对数据库有任何影响。

大家好,欢迎来到IT知识分享网。

1.事务前提知识

1.1 事务的特性

Spring 事务控制-第5天

  • 原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚,没有中间停留环节。因此事务的操作如果成功就必须要完全应用到数据库,如果操作失败则不能对数据库有任何影响。
  • 一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态。

拿转账来说,假设用户A和用户B两者的钱加起来一共是1000,那么不管A和B之间如何转账,转几次账,事务结束后两个用户的钱相加起来应该还得是1000,这就是事务的一致性。

  • 隔离性是当多个用户并发访问数据库时,比如操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离。

即要达到这么一种效果:对于任意两个并发的事务T1和T2,在事务T1看来,T2要么在T1开始之前就已经结束,要么在T1结束之后才开始,这样每个事务都感觉不到有其他事务在并发地执行。

  • 持久性

是指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。

1.2 事务的隔离级别

当多个线程都开启事务操作数据库中的数据时,数据库系统要能进行隔离操作,以保证各个线程获取数据的准确性,在介绍数据库提供的各种隔离级别之前,我们先看看如果不考虑事务的隔离性,会发生的几种问题:

A)脏读

脏读是指在一个事务处理过程里读取了另一个未提交的事务中的数据。如:用户A向用户B转账100元,对应SQL命令如下

update account set money=money+100 where name=’B’; (此时A通知B)
update account set money=money – 100 where name=’A’;

当只执行第一条SQL时,A通知B查看账户,B发现确实钱已到账(此时即发生了脏读),而之后无论第二条SQL是否执行,只要该事务不提交,则所有操作都将回滚,那么当B以后再次查看账户时就会发现钱其实并没有转。

B)不可重复读

不可重复读是指在对于数据库中的某个数据,一个事务范围内多次查询却返回了不同的数据值,这是由于在查询间隔,被另一个事务修改并提交了。

例如事务T1在读取某一数据,而事务T2立马修改了这个数据并且提交事务给数据库,事务T1再次读取该数据就得到了不同的结果,发送了不可重复读。

不可重复读和脏读的区别是,脏读是某一事务读取了另一个事务未提交的脏数据,而不可重复读则是读取了前一事务提交的数据

C)幻读

可重复读,在同一个事务内的查询都是事务开始时刻一致的;在可重复读中,该sql第一次读取到数据后,就将这些数据加锁(悲观锁),其它事务无法修改这些数据,就可以实现可重复读了.但这种方法却无法锁住insert的数据,所以当事务A先前读取了数据,或者修改了全部数据,事务B还是可以insert数据提交,这时事务A就会发现莫名其妙多了一条之前没有的数据,这就是幻读

现在列出事务的隔离级别为:

Spring 事务控制-第5天

1.3事务的传播行为

定义:事务传播行为是用来描述由某一个事务传播行为修饰的方法被嵌套进另一个方法时事务传播的规则

Spring 事务控制-第5天

后边通过案例介绍

2 Spring如何管理事务

Java EE应用的事务分为两种策略:全局事务和局部事务。全局事务由应用服务器管理,需要底层服务器的JTA 支持;局部事务和底层采用的持久化技术有关。
当采用JDBC 持久化技术时,需要使用Connection 对象来操作事务
当采用Hibernate 持久化技术时,需要使用Session 对象来操作事务。

两种事务操作对比:

Spring 事务控制-第5天

从上面的图,可以看出,如果采用传统的方式编程时,程序代码和具体的事务操作代码耦合性很强,这样会出现当应用程序在不同的事务策略之间切换时,开发者必须手动改动程序代码。
Spring 事务管理的策略可以很好的解决这种耦合的问题。根据不同的事务策略采用不同的实现类,PlatformTransactionManager 没有与任何事务资源捆绑。spring会根据配置文件来选择合适的事务策略来实现。

Spring 事务控制-第5天

2.1 事务的分类

从spring的角度把事务分为两类

2.1.1编程式事务

编程式事务是通过手动编码方式实现的事务管理方式。

2.1.2声明式事务

即是Spring中基于AOP,通过配置文件及注解实现的事务管理方式。(推荐使用重点讲解)

2.2 事务实现方式

2.2.1 案例需求

以转账的案例来说明事务实现的两种方式

Spring 事务控制-第5天

2.2.2 编程式事务

基于TransactionTemplate的编程式事务

Spring 事务控制-第5天

A)spring.xml配置

<bean id=”transactionManager” class=”org.springframework.jdbc.datasource.DataSourceTransactionManager”>
<property name=”dataSource” ref=”dataSource”/>
</bean>
<bean id=”transactionTemplate” class=”org.springframework.transaction.support.TransactionTemplate”>
<property name=”transactionManager” ref=”transactionManager”>
</property>
</bean>

B)cardServiceImpl

@Service
public class CardServiceImpl implements CardService {
//注入dao
@Autowired
private TransactionTemplate transactionTemplate; //注入事务模板类对象
//按照id修改银行卡余额方法
@Override
public boolean transferAccounts(int fromid, int toid, double money) {//转账方法
boolean result = (boolean) transactionTemplate.execute(new TransactionCallback<Object>() {
public Object doInTransaction(TransactionStatus status) {
Object result = true;
try {
updateBalance(fromid, money); //转出方金额减少
int i = 1/0 ; // random值为0和1分别测试有异常和无异常
updateBalance(toid, money); //转入方金额增加
} catch (Exception e) {
status.setRollbackOnly();//回滚
result = false;
}
return result;
}});
}
} }

2.2.3 声明式事务

即是Spring中基于AOP,通过配置文件及注解实现的事务管理方式

Spring 事务控制-第5天

####

2.2.3.1 注解配置

spring文件

<?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:aop=”http://www.springframework.org/schema/aop”
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
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd”>
<!–引入外部属性文件–>
<context:property-placeholder location=”classpath:db.properties”></context:property-placeholder>
<!–项目路径扫描–>
<context:component-scan base-package=”com.bw”></context:component-scan>
<!–配置数据源–>
<bean id=”dataSource” class=”com.alibaba.druid.pool.DruidDataSource”>
<property name=”driverClassName” value=”${jdbc.driver}”></property>
<property name=”url” value=”${jdbc.url}”></property>
<property name=”username” value=”${jdbc.username}”></property>
<property name=”password” value=”${jdbc.password}”></property>
</bean>
<!–sqlSessionFactoryBean–>
<bean id=”sqlSessionFactoryBean” class=”org.mybatis.spring.SqlSessionFactoryBean”>
<!–注入数据源–>
<property name=”dataSource” ref=”dataSource”></property>
<!–注入mybatis.xml–>
<property name=”configLocation” value=”classpath:mybatis.xml”></property>
<!–注入sql映射文件–>
<property name=”mapperLocations” value=”classpath:mappers/*.xml”></property>
</bean>
<!–扫描dao接口产生mapper接口代理类–>
<bean class=”org.mybatis.spring.mapper.MapperScannerConfigurer”>
<property name=”basePackage” value=”com.bw.dao”></property>
</bean>
<!–配置事务管理器–>
<bean id=”transactionManager” class=”org.springframework.jdbc.datasource.DataSourceTransactionManager”>
<property name=”dataSource” ref=”dataSource”></property>
</bean>
<!–开启事务注解–>
<tx:annotation-driven transaction-manager=”transactionManager”/>
</beans>

B)service 业务代码

Spring 事务控制-第5天

2.2.3.2 xml 配置实现

A) spring.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:aop=”http://www.springframework.org/schema/aop”
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
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd”>
<!–引入外部属性文件–>
<context:property-placeholder location=”classpath:db.properties”></context:property-placeholder>
<!–项目路径扫描–>
<context:component-scan base-package=”com.bw”></context:component-scan>
<!–配置数据源–>
<bean id=”dataSource” class=”com.alibaba.druid.pool.DruidDataSource”>
<property name=”driverClassName” value=”${jdbc.driver}”></property>
<property name=”url” value=”${jdbc.url}”></property>
<property name=”username” value=”${jdbc.username}”></property>
<property name=”password” value=”${jdbc.password}”></property>
</bean>
<!–sqlSessionFactoryBean–>
<bean id=”sqlSessionFactoryBean” class=”org.mybatis.spring.SqlSessionFactoryBean”>
<!–注入数据源–>
<property name=”dataSource” ref=”dataSource”></property>
<!–注入mybatis.xml–>
<property name=”configLocation” value=”classpath:mybatis.xml”></property>
<!–注入sql映射文件–>
<property name=”mapperLocations” value=”classpath:mappers/*.xml”></property>
</bean>
<!–扫描dao接口产生mapper接口代理类–>
<bean class=”org.mybatis.spring.mapper.MapperScannerConfigurer”>
<property name=”basePackage” value=”com.bw.dao”></property>
</bean>
<!–配置事务管理器–>
<bean id=”transactionManager” class=”org.springframework.jdbc.datasource.DataSourceTransactionManager”>
<property name=”dataSource” ref=”dataSource”></property>
</bean>
<!–开启事务注解–>
<!– <tx:annotation-driven transaction-manager=”transactionManager”/>–>
<!–事务属性配置–>
<tx:advice transaction-manager=”transactionManager” id=”tx”>
<tx:attributes>
<!–为了提高查询效率对查询的方法设置为只读事务–>
<tx:method name=”get*” read-only=”true”/>
<tx:method name=”list*” read-only=”true”/>
<tx:method name=”find*” read-only=”true”/>
<tx:method name=”select*” read-only=”true”/>
<tx:method name=”login*” read-only=”true”/>
<tx:method name=”search*” read-only=”true”/>
<!–其他为正常事务–>
<tx:method name=”*” propagation=”REQUIRED”></tx:method>
</tx:attributes>
</tx:advice>
<aop:config>
<!–配置切点表达式–>
<aop:pointcut id=”pt” expression=”execution(* com.bw.service.*.*(..))”/>
<aop:advisor advice-ref=”tx” pointcut-ref=”pt”></aop:advisor>
</aop:config>
</beans>

2.2.3.3 整体项目结构

Spring 事务控制-第5天

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/88206.html

(0)
上一篇 2024-10-12 08:26
下一篇 2024-10-14 07:00

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信