1、事务

1.1 什么是事务?

事务是用户定义的数据库操作的集合,这些操作作为一个完整的有机工作单元,要么全部正确执行,要么全部不执行。
四大特性:
(1)原子性(atomicity)。一个事务是一个不可分割的工作单位,事务中包括的操作要么都做,要么都不做。
(2)一致性(consistency)。事务必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。
(3)隔离性(isolation)。一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
(4)持久性(durability)。持续性也称永久性(permanence),指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。

1.2 事务的作用?

以银行转账为例,若业务方法没有事务时,假如在业务方法执行时发生异常,有可能会造成数据库数据不一致。
解决方法是在业务方法中加入事务。若发生异常,事务回滚(回滚方法由Spring事务自动完成,不需要自定义)。

2、Spring对事务的支持

2.1 Spring的事务管理主要包括3个接口

TransactionDefinition:封装事务的隔离级别,超时时间,是否为只读事务和事务的传播规则等事务属性,可通过XML配置具体信息。
PlatformTransactionManager:根据TransactionDefinition提供的事务属性配置信息,创建事务。
TransactionStatus:封装了事务的具体运行状态。比如,是否是新开启事务,是否已经提交事务,设置当前事务为rollback-only等。

2.2 Spring的事务管理

1,PlatformTransactionManager:接口统一,抽取处理事务操作相关的方法;
(1):TransactionStatus getTransaction(TransactionDefinition definition):
根据事务定义信息从事务环境中返回一个已存在的事务,或者创建一个新的事务,并用TransactionStatus描述该事务的状态。
(2):void commit(TransactionStatus status):
根据事务的状态提交事务,如果事务状态已经标识为rollback-only,该方法执行回滚事务的操作。
(3):void rollback(TransactionStatus status):
将事务回滚,当commit方法抛出异常时,rollback会被隐式调用
2,在使用spring管理事务的时候,首先得告诉spring使用哪一个事务管理器; 看图
3,常用的事务管理器:
DataSourceTransactionManager:使用JDBC,MyBatis的事务管理器;
HibernateTransactionManager:使用Hibernate的事务管理器;

3、Spring事务的配置—>xml方式

模拟在数据库中两个用户转账的案例。

3.1 准备Service层及Dao层相关类


(1) 业务层完成转账方法:

public class AccountServiceImpl implements IAccountService {@Setterprivate IAccountDao dao;public void trans(Integer inId, Integer outId, Integer money) {//转出this.transOut(outId,money);//转入this.transIn(inId,money);public void transIn(Integer inId, Integer money) {dao.transIn(inId,money);}public void transOut(Integer outId, Integer money) {dao.transOut(outId,money);}}

(2)数据库层完成转入和转出方法

public class AccountDaoImpl implements IAccountDao {/*通过Spring JDBC获取数据库连接对象*/private JdbcTemplate jdbcTemplate;public void setDataSource(DataSource dataSource){this.jdbcTemplate = new JdbcTemplate(dataSource);}/*转入*/public void transIn(Integer inId, Integer money) {jdbcTemplate.update("update bank_count set money = money + ? where count_id = ?",money,inId);}/*转出*/public void transOut(Integer outId, Integer money) {jdbcTemplate.update("update bank_count set money = money - ? where count_id = ?",money,outId);}
}

3.2 配置事务管理器

1.首先要配置事务管理器,JDBC和Mybatis使用的事务管理器是org.springframework.jdbc.datasource.DataSourceTransactionManager
2.事务管理器需要配置dataSource属性
3.配置Advice需要关联事务管理器.假如不配置transaction-manager属性.会自动关联容器中名字为"transactionManager"的事务管理器.
4.配置aop,将pointcut和advice关联

<?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsd"><context:property-placeholder location="classpath:db.properties" system-properties-mode="NEVER"/><bean id="datasource" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="${driver}"/><property name="url" value="${url}"/><property name="username" value="${username}"/><property name="password" value="${password}"/></bean><bean id="service" class="com.project.TransactionManager.service.impl.AccountServiceImpl"><property name="dao" ref="dao"/></bean><bean id="dao" class="com.project.TransactionManager.dao.impl.AccountDaoImpl"><property name="DataSource" ref="datasource"/></bean><!--配置Spring的事务控制,在AOP的基础上实现,出现错误自动回滚--><!--增加事务管理器--><bean id="manager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><!--配置jdbc连接池对象--><property name="dataSource" ref="datasource"/></bean><!-- xml配置事务--><aop:config><aop:pointcut id="point" expression="execution( * com.project.TransactionManager.service.IAccountService.*(..))"/><aop:advisor advice-ref="advice" pointcut-ref="point"/></aop:config><!-- 事务增强器--><tx:advice id="advice" transaction-manager="manager"><tx:attributes><!--查询方法时设置为只读事务,非查询的方法时设置非只读事务通用的一个事务管理器:--><tx:method name="select*" read-only="true"/><tx:method name="find*" read-only="true"/><tx:method name="*"/><!--或:只配置业务方法名(不推荐)<tx:method name="trans"/>--></tx:attributes></tx:advice>

3.3 测试

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class App {@Autowiredprivate IAccountService service;@Testpublic void testTrans() throws Exception {//1号给2号转钱service.trans(2,1,1000);}
}

3.4 小结

1.事务方法的属性细节:
name属性为必须属性,可以使用通配符*
查询的方法read-only设置为"true",可以提升查询的执行效率.

2 通用的事务配置

4、Spring事务的配置—>注解方式

4.1 添加事务的注解解析器

打开spring的xml配置文件,添加事务的注解解析器,注解解析器需要关联事务处理器
<tx:annotation-driven transaction-manager=“transactionManager”/>

<?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsd"><context:property-placeholder location="classpath:db.properties" system-properties-mode="NEVER"/><bean id="datasource" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="${driver}"/><property name="url" value="${url}"/><property name="username" value="${username}"/><property name="password" value="${password}"/></bean><bean id="service" class="com.project.TransactionManager.service.impl.AccountServiceImpl"><property name="dao" ref="dao"/></bean><bean id="dao" class="com.project.TransactionManager.dao.impl.AccountDaoImpl"><property name="DataSource" ref="datasource"/></bean><!--配置Spring的事务控制,在AOP的基础上实现,出现错误自动回滚--><!--增加事务管理器--><bean id="manager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><!--配置jdbc连接池对象--><property name="dataSource" ref="datasource"/></bean><!--注解配置事务管理器(1)只需要在xml中配置事务注解驱动(2)在业务类的实现类上加注解@Transactional--><tx:annotation-driven transaction-manager="manager"/></beans>

4.2 在业务层的实现类上加注解@Transactional

(1)注解中相应的属性可以配置事务控制的相关细节(隔离级别/传播规则/是否只读等)
(2)类中的方法也可以添加@Transactional注解,同样可以对方法进行细节配置.方法中的配置信息会覆盖类中的同名配置.

@Transactional(readOnly = false)
public class AccountServiceImpl implements IAccountService {@Setterprivate IAccountDao dao;//@Transactional(readOnly = true)public void trans(Integer inId, Integer outId, Integer money) {//转出this.transOut(outId,money);System.out.println(1/0);//转入this.transIn(inId,money);}public void transIn(Integer inId, Integer money) {dao.transIn(inId,money);}public void transOut(Integer outId, Integer money) {dao.transOut(outId,money);}}

Spring事务(Transactions)的原理与实现相关推荐

  1. 《深入理解分布式事务》第三章 Spring 事务的实现原理

    <深入理解分布式事务>第三章 Spring 事务的实现原理 文章目录 <深入理解分布式事务>第三章 Spring 事务的实现原理 一.Spring 事务原理 1.JDBC 直接 ...

  2. jdbctemplate 开启事务_浅入浅出 Spring 事务传播实现原理

    本文和大家一起刨析 Spring 事务的相关源码,篇幅较长,代码片段较多,建议使用电脑阅读 本文目标 理解Spring事务管理核心接口 理解Spring事务管理的核心逻辑 理解事务的传播类型及其实现原 ...

  3. Spring事务的实现原理

    目录 一.Spring事务分类 二.Spring事务的三大接口 2.1 PlatformTransationManager接口 2.2 TransactionDefinition接口 2.3 Tran ...

  4. Spring事务传播实现原理

    什么是事务传播? 假设这样一个场景:方法A上面添加了一个@Transactional注解,在该方法中去调用另一个Service的方法B,但方法B并不需要事务,但是由于A开启了事务,导致B方法的执行也处 ...

  5. Spring 事务用法示例与实现原理

    关于事务,简单来说,就是为了保证数据完整性而存在的一种工具,其主要有四大特性:原子性,一致性,隔离性和持久性.对于Spring事务,其最终还是在数据库层面实现的,而Spring只是以一种比较优雅的方式 ...

  6. Spring事务原理一探

    概括来讲,事务是一个由有限操作集合组成的逻辑单元.事务操作包含两个目的,数据一致以及操作隔离.数据一致是指事务提交时保证事务内的所有操作都成功完成,并且更改永久生效:事务回滚时,保证能够恢复到事务执行 ...

  7. 【技术干货】Spring事务原理一探

    本篇文章是网易云信研发工程师对Spring事务实现原理及实现的研究和总结,分享给大家,希望和大家共同探讨. 事务是一个由有限操作集合组成的逻辑单元.事务操作包含两个目的,数据一致以及操作隔离.数据一致 ...

  8. Spring事务实现的方式及底层原理

    spring事务的实现方式 spring框架提供了两种事务实现方式:编程式事务.声明式事务 编程式事务:在代码中进行事务控制.优点:精度高.缺点:代码耦合度高 声明式事务:通过@Transaction ...

  9. Spring 事务原理篇:@EnableTransactionManagement注解底层原理分析技巧,就算你看不懂源码,也要学会这个技巧!

    前言 学习了关于Spring AOP原理以及事务的基础知识后,今天咱们来聊聊Spring在底层是如何操作事务的.如果阅读到此文章,并且对Spring AOP原理不太了解的话,建议先阅读下本人的这篇文章 ...

  10. Spring事务原理-1-transactionManager以及Connection的本质

    Spring事务原理 1.spring事务配置 2.Connection本质的探究 3. Spring事务的底层原理 1.spring事务配置 <bean id="transactio ...

最新文章

  1. 使用 IDEA 开发工具(版本为 IntelliJ IDEA 14.1.4)打可执行jar包的操作步骤
  2. 使用渲染纹理的制作摄像头
  3. 从库存管理系统,体验活字格强大的移动端应用开发能力
  4. 市面主要远场语音交互技术架构
  5. domino流程图_OA实施工程师一线解读Java与Domino优劣
  6. PAT乙级(1036 跟奥巴马一起编程)
  7. 测试面试题集-Python编程题(1)
  8. 第 12 章 执行引擎
  9. 图片相似度识别在线_玩转腾讯词向量:词语相似度计算和在线查询
  10. 论文降重的主要内容有什么?
  11. 史诗级Java入门教程,想成为初级程序员看他就够了
  12. 同济大学Openwrt路由器 ipv6教程(新手导向)
  13. 面试记录-蚂蚁金服-算法工程师(共四面)通过
  14. 关于DDoS攻击的8个误区
  15. python vcf转换xls的简单实现
  16. 关于组装电脑注意事项
  17. 2021C语言全套教程
  18. [redis] 10 种数据结构详解
  19. connect() failed (111 Connection refused) while connecting to upstream
  20. linux webdav 乱码,webDav遇到的乱码问题

热门文章

  1. 持NPDP和PMP证书,可以享受深圳、北京等多项福利!
  2. CPLEX运行出错-OPL标记问题
  3. K8S 探针 readinessProbe、livenessProbe和startupProbe
  4. TP-LINK路由器如何设置DHCP
  5. 路由器和三层交换机区别
  6. 写论文的公式怎么写最便捷?
  7. Word怎么转PDF?分享三种非常简单的方法
  8. python乌龟赛跑_Python之龟兔赛跑
  9. 四分位数计算方法总结
  10. SeleniumWebdriver参数化详解