事务管理

  • 1、案例:转账
    • 1.1、需求描述:
    • 1.2、环境搭建
    • 1.3、编写domain
    • 1.4、编写dao
    • 1.5、编写service
    • 1.6、配置类
    • 1.6、测试
  • 2、事务概述
  • 3、Spring事务相关的术语
    • 3.1、事务平台管理器:PlatformTransactionManager
  • 4、事务入门
    • 4.1、修改配置类
    • 4.2、修改Service
  • 5、事务高级
    • 5.1、事务特性:ACID
    • 5.2、并发访问问题
    • 5.3、隔离级别:解决问题
    • 5.4、术语
    • 5.5、定义对象:概述TransactionDefinition
    • 5.6、定义对象:只读
    • 5.7、定义对象:超时
    • 5.8、定义对象:隔离级别
    • 5.9、定义对象:传播行为

  • 事务指的是逻辑上的一组操作,组成这组操作的各个单元要么全都成功,要么全都失败.
  • 事务作用:保证一组操作要么全都成功,对数据库进行完整更新。要么在某一个动作失败的时候让数据恢复原状,不会引起不完整的修改。

1、案例:转账

1.1、需求描述:

完成转账功能, 根据两个账户的id和要转账的钱money,对其中一个id的钱-money,对另一个id的钱+money.

分析:
转账功能 需要由两个动作完成.
1)账户1减钱
2)账户2加钱

减钱:根据账户id对钱数 减
加钱:根据账户id 对钱数 加

总体思路:
1.SM整合环境搭建好.
2.在service中提供转账功能.
3.测试类中测试.转账功能

项目结构如下:

1.2、环境搭建

  1. 步骤1:导入jar包坐标
  2. 步骤2:配置文件
  3. 步骤3:数据库和表

CREATE TABLE account(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(40),
money FLOAT
)
INSERT INTO account(NAME,money) VALUES(‘jack’,10);
INSERT INTO account(NAME,money) VALUES(‘rose’,10);

1.3、编写domain

@Entity(name = “accnout”)
public class Account {
@Id
private Integer id;
private String name;
//省略getter和setter方法
}

1.4、编写dao

public interface AccnoutMapper extends Mapper {
}

1.5、编写service

AccountService接口:

public interface AccnoutService {
public void change(Integer inId,Integer outId,Double money);
}

AccountServiceImpl实现类:

@Service
@Transactional()
public class AccnoutServiceImpl implements AccnoutService {
@Resource
private AccnoutMapper accnoutMapper;
@Override
public void change(Integer inId, Integer outId, Double money) {
//收款人+加钱
Account account = accnoutMapper.selectByPrimaryKey(inId);
account.setMoney(account.getMoney()+money);
accnoutMapper.updateByPrimaryKey(account);
//汇款人-减钱
Account account1 = accnoutMapper.selectByPrimaryKey(outId);
account1.setMoney(account1.getMoney()-money);
accnoutMapper.updateByPrimaryKey(account1);
}
}

1.6、配置类

MyBatisConfig 类

public class MyBatisConfig {
@Bean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
sqlSessionFactoryBean.setTypeAliasesPackage(“com.czxy.sm.domain”);
Configuration configuration = new Configuration();
configuration.setMapUnderscoreToCamelCase(true);
sqlSessionFactoryBean.setConfiguration(configuration);
//分页
PageHelper pageHelper = new PageHelper();
Properties properties = new Properties();
properties.setProperty(“dialect”,“mysql”);
properties.setProperty(“rowBoundsWithCount”,“true”);
pageHelper.setProperties(properties);
sqlSessionFactoryBean.setPlugins(new Interceptor[]{pageHelper});
return sqlSessionFactoryBean.getObject();
}
/**
* 扫描Dao的包,查找各种XxxMapper接口,创建好UserMapper等对象存入到IOC的容器中
* @return
*/
@Bean
public MapperScannerConfigurer mapperScannerConfigurer(){
MapperScannerConfigurer configurer = new MapperScannerConfigurer();
configurer.setBasePackage(“com.czxy.sm.dao”);
return configurer;
}
}

SpringConfiguiation 类

@Configuration
@PropertySource(“classpath:db.properties”)
@ComponentScan({“com.czxy.sm.dao”,“com.czxy.sm.service”})
public class SpringConfiguiation {
@Value("jdbc.driver")privateStringdriver;@Value("{jdbc.driver}") private String driver; @Value("jdbc.driver")privateStringdriver;@Value("{jdbc.url}")
private String url;
@Value("jdbc.username")privateStringusername;@Value("{jdbc.username}") private String username; @Value("jdbc.username")privateStringusername;@Value("{jdbc.password}")
private String password;
@Bean
public DataSource dataSource(){
DruidDataSource druidDataSource = new DruidDataSource();
druidDataSource.setDriverClassName(driver);
druidDataSource.setUrl(url);
druidDataSource.setUsername(username);
druidDataSource.setPassword(password);
return druidDataSource;
}

1.6、测试

@RunWith(SpringRunner.class)
@ContextConfiguration(classes = {SpringConfiguiation.class, MyBatisConfig.class})
public class TestSm {
@Resource
private AccnoutService accnoutService;
@Test
public void run1(){
accnoutService.change(1,2,3.0);
System.out.println(“完毕”);
}
}

2、事务概述

JavaEE体系进行分层开发,事务处理位于业务层,Spring提供了分层设计业务层的事务处理解决方案。
spring的事务控制是基于AOP的。也就是spring提供了实现类对我们的业务方法进行增强,完成事务具体的操作。

3、Spring事务相关的术语

3.1、事务平台管理器:PlatformTransactionManager

spring通过事务管理器来管理事务。
事务管理器PlatformTransactionManager提供了事务需要的基本操作

实现类:DataSourceTransactionManager:使用JdbcTemplate或MyBatis需要的事务管理器

4、事务入门

4.1、修改配置类

加粗为修改内容

@ComponentScan(basePackages={“com.czxy”})
@PropertySource(“classpath:jdbc.properties”) //加载配置文件
@EnableTransactionManagement
public class SpringConfigruation {
//解析 jdbc.driver在4.2.4中必须配置内容@BeanpublicstaticPropertySourcesPlaceholderConfigurerconfigurer()returnnewPropertySourcesPlaceholderConfigurer();/∗∗∗获得数据∗/@Value("{jdbc.driver} 在 4.2.4中必须配置内容 @Bean public static PropertySourcesPlaceholderConfigurer configurer(){ return new PropertySourcesPlaceholderConfigurer(); } /** * 获得数据 */ @Value("jdbc.driver在4.2.4中必须配置内容@BeanpublicstaticPropertySourcesPlaceholderConfigurerconfigurer()returnnewPropertySourcesPlaceholderConfigurer();/∗∗∗获得数据∗/@Value("{jdbc.driver}")
private String driverClass;
@Value("jdbc.url")privateStringurl;@Value("{jdbc.url}") private String url; @Value("jdbc.url")privateStringurl;@Value("{jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
/**
* 配置数据源
* @return
/
@Bean
public DataSource dataSource(){
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(driverClass);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
return dataSource;
}
/
* 事务管理器
* @param dataSource
* @return
/
@Bean
public DataSourceTransactionManager txManager(DataSource dataSource){
return new DataSourceTransactionManager(dataSource);
}

}

4.2、修改Service

加粗为修改内容

@Service
@Transactional
public class AccountServiceImpl implements AccountService {
@Autowired
private AccountMapper accountMapper;
public void change(Integer inId, Integer outId, Double money) {
Account account = accountMapper.selectByPrimaryKey(inId);
account.setMoney(account.getMoney()+money);
accountMapper.updateByPrimaryKey(account);
// int i=1/0;
Account account1 = accountMapper.selectByPrimaryKey(outId);
account1.setMoney(account1.getMoney()-money);
accountMapper.updateByPrimaryKey(account1);
}
}

5、事务高级

5.1、事务特性:ACID

  • 原子性(Atomicity)原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
  • 一致性(Consistency)事务前后数据的完整性必须保持一致。
  • 隔离性(Isolation)事务的隔离性是指多个用户并发访问数据库时,一个用户的事务不能被其它用户的事务所干扰,多个并发事务之间数据要相互隔离。
  • 持久性(Durability)持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响。

5.2、并发访问问题

如果不考虑隔离性,事务存在并发访问问题。
1.脏读:一个事务读到了另一个事务未提交的数据.

2.不可重复读:一个事务读到了另一个事务已经提交(update)的数据。引发另一个事务,在事务中的多次查询结果不一致。

3.虚读 /幻读:一个事务读到了另一个事务已经提交(insert)的数据。导致另一个事务,在事务中多次查询的结果不一致。(数据量不同)

严重性: 脏读 > 不可重复读 >虚读(幻读)

5.3、隔离级别:解决问题

  • 数据库规范规定了4种隔离级别,分别用于描述两个事务并发的所有情况。
  1. read uncommitted 读未提交,一个事务读到另一个事务没有提交的数据。
    a)存放:3个问题(脏读、不可重复读、虚读)。
    b)解决:0个问题

效率最高,引发所有读问题
基本不设置

  1. read committed 读已提交,一个事务读到另一个事务已经提交的数据。
    a)存放:2个问题(不可重复读、虚读)。
    b)解决:1个问题(脏读)

如果要 效率,那么选择这个read committed

  1. repeatable read :可重复读,在一个事务中读到的数据信息始终保持一致,无论另一个事务是否提交。
    a)存放:1个问题(虚读)。
    b)解决:2个问题(脏读、不可重复读)

如果 要求安全,选择这个repeatable read

虚读的问题可以通过程序来规避:
1)事务刚开启时,可以count()
2)事务要关闭时,可以count(
)
3)比对,如果两次数据一致,说明没有虚读

  1. serializable 串行化,同时只能执行一个事务,相当于事务中的单线程。
    a)存放:0个问题。
    b)解决:1个问题(脏读、不可重复读、虚读)

没有效率,安全性最高,基本不设置

  • 安全和性能对比
  • 安全性:serializable > repeatable read > read committed > read uncommitted
  • 性能 : serializable < repeatable read < read committed < read uncommitted
  • 常见数据库的默认隔离级别:
  • MySql:repeatable read 安全,本身做的优化比较好
  • Oracle:read committed 效率

5.4、术语

事务:

TransactionDefinition:事务的定义信息对象,需要知道,方便知道事务有哪些设置项。
TransactionStatus:事务的状态对象,spring内部使用的对象,不需要关注。

5.5、定义对象:概述TransactionDefinition


通过分析事务定义信息对象,spring事务定义主要涉及以下4方面:隔离级别、传播行为、超时、只读

5.6、定义对象:只读

开发中,查询数据,不会伴随增删改,所以建议查询时设置为只读。

注解
@Transactional(readOnly=true):只读事务。DQL使用
@Transactional(readOnly=false):默认值,不是只读事务,可以进行增删改操作。DML使用

5.7、定义对象:超时

默认值是-1,没有超时限制。如果有,以秒为单位进行设置。(一般不设置)
注解
@Transactional(timeout=60):设置超时为60秒,如果还没有操作结束,将抛异常。

5.8、定义对象:隔离级别

事务隔离级别反映事务提交并发访问时的处理态度。
注解
@Transactional(isolation=Isolation.DEFAULT):默认级别
@Transactional(isolation=Isolation.READ_UNCOMMITTED):读未提交
@Transactional(isolation=Isolation.READ_COMMITTED):读已提交
@Transactional(isolation=Isolation.REPEATABLE_READ):可重复读
@Transactional(isolation=Isolation.SERIALIZABLE):串行化

5.9、定义对象:传播行为

传播行为:业务A使用了业务B,AB之间事务共享问题,就是事务的传播行为。
spring中事务的传播行为共7种。
注解
@Transactional(propagation=Propagation.REQUIRED):默认值,支持当前事务,如果当前没有事务,就新建一个事务
@Transactional(propagation=Propagation.SUPPORTS):支持当前事务,如果当前没有事务,就以非事务方式执行
@Transactional(propagation=Propagation.MANDATORY):支持当前事务,如果当前没有事务,就抛出异常
@Transactional(propagation=Propagation.REQUIRES_NEW):新建事务,如果当前存在事务,把当前事务挂起
@Transactional(propagation=Propagation.NOT_SUPPORTED):以非事务方式执行操作,如果当前存在事务,就把当前事务挂起
@Transactional(propagation=Propagation.NEVER):以非事务方式执行,如果当前存在事务,则抛出异常
@Transactional(propagation=Propagation.NESTED):如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行REQUIRED类似的操作

❤️‍Spring从入门到大神--事务管理(搞笑漫画讲解!简单易懂!!)相关推荐

  1. ❤️‍Spring从入门到大神--AOP从入门到精通

    文章目录 1.AOP介绍 2. 入门案例 2.1.需求: 2.2.实现思路: 3.AOP作用和优势 4. 入门案例2 4.1.需求 5.AOP实现方法 6.相关AOP术语 7.相关注解 7.1.切入点 ...

  2. spring3.2入门到大神(备java基础、jsp、servlet,javaee精髓)-任亮-专题视频课程

    spring3.2入门到大神(备java基础.jsp.servlet,javaee精髓) 课程介绍         框架介绍,IoC思想.DI依赖注入.Bean的实例方式.Bean种类.Bean作用域 ...

  3. oracle入门到大神(备mysql、java基础、javaee必经之路)-任亮-专题视频课程

    oracle入门到大神(备mysql.java基础.javaee必经之路)-19178人已学习 课程介绍         Oracle10g的安装.orcale的基本概念介绍.命令行常用操作.Scot ...

  4. Activiti 工作流入门到大神-任亮-专题视频课程

    Activiti 工作流入门到大神-16384人已学习 课程介绍         什么是流程.工作流作用.Activiti背景简介.Activiti流程设计器安装.Activity环境搭建.通过Hel ...

  5. Spring中两种编程式事务管理

    Spring中两种编程式事务管理 在代码中显示调用beginTransaction,commit,rollback等与事务处理相关的方法,这就是编程式事务管理,当只有少数事务操作时,编程式事务管理才比 ...

  6. spring框架学习 - Data Access之 事务管理 - 声明式事务管理

    接上一篇博客:https://blog.csdn.net/qq_43605444/article/details/122085016?spm=1001.2014.3001.5502 4.声明式事务管理 ...

  7. python类中的属性分为类属性和实例属性两种_python从入门到大神---1、初始化实例、类属性、方法...

    python从入门到大神---1.初始化实例.类属性.方法 一.总结 一句话总结: 方法不加括号是代码段:感觉python方法和js,php很类似,不加括号是代码段,加括号变成方法,比如f,f() 1 ...

  8. Spring整合JMS(四)——事务管理

    2019独角兽企业重金招聘Python工程师标准>>> Spring整合JMS(四)--事务管理 博客分类: Spring Jms SpringJMS事务sessionTransac ...

  9. python从入门到大神系列手机_python从入门到大神---2、和Python编程相遇的日子

    python从入门到大神---2.和Python编程相遇的日子 一.总结 一句话总结: python2和python3是很不同的,连语法都不同,比如 print 函数打印结果 1.python中pip ...

最新文章

  1. 2021年大数据Hadoop(九):HDFS的高级使用命令
  2. 修改mysql   默认字符集 , 默认引擎
  3. sendto 返回errnor 1,错误码1 Operation not permitted
  4. SAP SD基本业务总结
  5. 蓝桥杯2017初赛-k倍区间-前缀和
  6. DT100pro上手体验
  7. Boost学习之正则表达式--regex
  8. python三大神器装饰器_Python2.x
  9. 视频|每日CeBIT:沃森机器人走进生活、三星无线很便利
  10. 小鹏汽车首批量产车下线,未来将进军L4级别自动驾驶
  11. Win7简单方法让笔记本变身无线热点,共享手机上网
  12. Vue开发与调试工具vue-devtools
  13. 如何查出一个表中重复的名字
  14. 图层蒙版和快速蒙版、路径
  15. 注意:这些跳槽理由会被HR调查!
  16. 华为matebook鸿蒙,16寸专业大屏+满血Zen3!华为MateBook 16评测:鸿蒙加持 平板变身新外设...
  17. java cas logout无效_CAS logout 解决方案
  18. [PHP] 2018年终总结
  19. 基于 RDD 的分布式数据处理实验(pyspark)
  20. 武汉移动137和武汉电信189手机业务比较

热门文章

  1. python英汉字典,Python基于有道实现英汉字典功能,python英汉字典
  2. BUUCTF 你尽然赶我走
  3. 打破应试教育,犯错亦是成长
  4. python中的数据类型有哪些是可阅读_Python list data type(list)[学习Python的必要基础知识][阅读本文],列表,数据类型,必备,看此,一篇,就够,了...
  5. JAVA小实验——接口与继承
  6. 成都信息工程大学计算机网络技术题库,2017年成都信息工程大学计算机学院341农业知识综合三[专业硕士]之计算机网络考研题库...
  7. View onMeasure 方法
  8. 有哪些编辑图片加文字的软件?这些软件值得收藏
  9. 教室机房平面图_计算机教室建设方案详细
  10. keydown与keypress的区别,组合键