导航:首页 > 程序命令 > 程序员代码重复执行

程序员代码重复执行

发布时间:2022-12-16 08:22:56

A. 程序员新人周一优化一行代码,周三被劝退

这周一,公司新来了一个同事,面试的时候表现得非常不错,各种问题对答如流,老板和我都倍感欣慰。

这么优秀的人,绝不能让他浪费一分一秒,于是很快,我就发他了需求文档、源码,让他先在本地熟悉一下业务和开发流程。

结果没想到,周三大家一块 review 代码的时候就发现了问题,新来的同事直接把原来 @Transactional 优化成了这个鬼样子:

就因为这一行代码,老板(当年也是一线互联网大厂的好手)当场就发飙了,马上就要劝退这位新同事,我就赶紧打圆场,毕竟自己面试的人,不看僧面看佛面,是吧?于是老板答应我说再试用一个月看看。

会议结束后,我就赶紧让新同事复习了一遍事务,以下是他自己做的总结,还是非常详细的,分享出来给大家一点点参考和启发。相信大家看完后就明白为什么不能这样优化 @Transactional 注解了,纯属画蛇添足和乱用。

事务在逻辑上是一组操作, 要么执行,要不都不执行 。主要是针对数据库而言的,比如说 MySQL。

只要记住这一点,理解事务就很容易了。在 java 中,我们通常要在业务里面处理多个事件,比如说编程喵有一个保存文章的方法,它除了要保存文章本身之外,还要保存文章对应的标签,标签和文章不在同一个表里,但会通过在文章表里(posts)保存标签主键(tag_id)来关联标签表(tags):

那么此时就需要开启事务,保证文章表和标签表中的数据保持同步,要么都执行,要么都不执行。

否则就有可能造成,文章保存成功了,但标签保存失败了,或者文章保存失败了,标签保存成功了——这些场景都不符合我们的预期。

为了保证事务是正确可靠的,在数据库进行写入或者更新操作时,就必须得表现出 ACID 的 4 个重要特性:

其中,事务隔离又分为 4 种不同的级别,包括:

需要格外注意的是: 事务能否生效,取决于数据库引擎是否支持事务,MySQL 的 InnoDB 引擎是支持事务的,但 MyISAM 就不支持

1)编程式事务

编程式事务是指将事务管理代码嵌入嵌入到业务代码中,来控制事务的提交和回滚。

你比如说,使用 TransactionTemplate 来管理事务:

再比如说,使用 TransactionManager 来管理事务:

就编程式事务管理而言,Spring 更推荐使用 TransactionTemplate。

在编程式事务中,必须在每个业务操作中包含额外的事务管理代码,就导致代码看起来非常的臃肿,但对理解 Spring 的事务管理模型非常有帮助。

当然了,要想实现事务管理和业务代码的抽离,就必须得用到 Spring 当中最关键最核心的技术之一,AOP,其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,执行完目标方法之后根据执行的情况提交或者回滚。

Spring 将事务管理的核心抽象为一个事务管理器(TransactionManager),它的源码只有一个简单的接口定义,属于一个标记接口:

通过 PlatformTransactionManager 这个接口,Spring 为各个平台如 JDBC(DataSourceTransactionManager)、Hibernate(HibernateTransactionManager)、JPA(JpaTransactionManager)等都提供了对应的事务管理器,但是具体的实现就是各个平台自己的事情了。

参数 TransactionDefinition 和 @Transactional 注解是对应的,比如说 @Transactional 注解中定义的事务传播行为、隔离级别、事务超时时间、事务是否只读等属性,在 TransactionDefinition 都可以找得到。

返回类型 TransactionStatus 主要用来存储当前事务的一些状态和数据,比如说事务资源(connection)、回滚状态等。

TransactionDefinition.java:

Transactional.java

说到这,我们来详细地说明一下 Spring 事务的传播行为、事务的隔离级别、事务的超时时间、事务的只读属性,以及事务的回滚规则。

当事务方法被另外一个事务方法调用时,必须指定事务应该如何传播 ,例如,方法可能继续在当前事务中执行,也可以开启一个新的事务,在自己的事务中执行。

TransactionDefinition 一共定义了 7 种事务传播行为:

01、 PROPAGATION_REQUIRED

这也是 @Transactional 默认的事务传播行为,指的是如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。更确切地意思是:

这个传播行为也最好理解,aMethod 调用了 bMethod,只要其中一个方法回滚,整个事务均回滚。

02、 PROPAGATION_REQUIRES_NEW

创建一个新的事务,如果当前存在事务,则把当前事务挂起。也就是说不管外部方法是否开启事务,Propagation.REQUIRES_NEW 修饰的内部方法都会开启自己的事务,且开启的事务与外部的事务相互独立,互不干扰。

如果 aMethod()发生异常回滚,bMethod()不会跟着回滚,因为 bMethod()开启了独立的事务。但是,如果 bMethod()抛出了未被捕获的异常并且这个异常满足事务回滚规则的话,aMethod()同样也会回滚。

03、 PROPAGATION_NESTED

如果当前存在事务,就在当前事务内执行;否则,就执行与 PROPAGATION_REQUIRED 类似的操作。

04、 PROPAGATION_MANDATORY

如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。

05、 PROPAGATION_SUPPORTS

如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。

06、 PROPAGATION_NOT_SUPPORTED

以非事务方式运行,如果当前存在事务,则把当前事务挂起。

07、 PROPAGATION_NEVER

以非事务方式运行,如果当前存在事务,则抛出异常。

3、4、5、6、7 这 5 种事务传播方式不常用,了解即可。

前面我们已经了解了数据库的事务隔离级别,再来理解 Spring 的事务隔离级别就容易多了。

TransactionDefinition 中一共定义了 5 种事务隔离级别:

通常情况下,我们采用默认的隔离级别 ISOLATION_DEFAULT 就可以了,也就是交给数据库来决定,可以通过 SELECT @@transaction_isolation; 命令来查看 MySql 的默认隔离级别,结果为 REPEATABLE-READ,也就是可重复读。

事务超时,也就是指一个事务所允许执行的最长时间,如果在超时时间内还没有完成的话,就自动回滚。

假如事务的执行时间格外的长,由于事务涉及到对数据库的锁定,就会导致长时间运行的事务占用数据库资源。

如果一个事务只是对数据库执行读操作,那么该数据库就可以利用事务的只读属性,采取优化措施,适用于多条数据库查询操作中。

这是因为 MySql(innodb)默认对每一个连接都启用了 autocommit 模式,在该模式下,每一个发送到 MySql 服务器的 SQL 语句都会在一个单独的事务中进行处理,执行结束后会自动提交事务。

那如果我们给方法加上了 @Transactional 注解,那这个方法中所有的 SQL 都会放在一个事务里。否则,每条 SQL 都会单独开启一个事务,中间被其他事务修改了数据,都会实时读取到。

有些情况下,当一次执行多条查询语句时,需要保证数据一致性时,就需要启用事务支持。否则上一条 SQL 查询后,被其他用户改变了数据,那么下一个 SQL 查询可能就会出现不一致的状态。

默认情况下,事务只在出现运行时异常(Runtime Exception)时回滚,以及 Error,出现检查异常(checked exception,需要主动捕获处理或者向上抛出)时不回滚。

如果你想要回滚特定的异常类型的话,可以这样设置:

以前,我们需要通过 XML 配置 Spring 来托管事务,有了 Spring Boot 之后,一切就变得更加简单了,只需要在业务层添加事务注解( @Transactional )就可以快速开启事务。

也就是说,我们只需要把焦点放在 @Transactional 注解上就可以了。

虽然 @Transactional 注解源码中定义了很多属性,但大多数时候,我都是采用默认配置,当然了,如果需要自定义的话,前面也都说明过了。

1)要在 public 方法上使用,在类的computeTransactionAttribute方法中有个判断,如果目标方法不是public,则TransactionAttribute返回null,即不支持事务。

2)避免同一个类中调用 @Transactional 注解的方法,这样会导致事务失效。

在测试之前,我们先把 Spring Boot 默认的日志级别 info 调整为 debug,在 application.yml 文件中 修改:

然后,来看修改之前查到的数据:

开搞。在控制器中添加一个 update 接口,准备修改数据,打算把沉默王二的狗腿子修改为沉默王二的狗腿:

在 Service 中为方法加上 @Transactional 注解并抛出运行时异常:

按照我们的预期,当执行 save 保存数据后,因为出现了异常,所以事务要回滚。所以数据不会被修改。

在浏览器中输入 http://localhost:8080/user/update 进行测试,注意查看日志,可以确认事务起效了。

当我们把事务去掉,同样抛出异常:

再次执行,发现虽然程序报错了,但数据却被更新了。

这也间接地证明,我们的 @Transactional 事务起效了。

看到这,是不是就明白为什么新同事的优化纯属画蛇添足/卵用了吧?

B. 中国的程序员,真的“短命”吗

程序员工作强度大,可能经常会有报道说各种猝死之类的,但是各行各业都有这样的情况。只是程序员的报道出来了。程序员经常加班是真的,因为工作强度大,所以工资都比较高。

C. 怎么利用BAT打开同一个程序多次

@echooff
title关闭本窗口即可停止打开程序
:head
cls
call你的程序.exe
goto:head
rem这个批处理打开程序后,会等待程序运行结束,程序运行结束后,才会再次打开程序

D. 要做程序员需要学会什么

其实简单来说,程序员的工作就是使用编程语言,根据需求写出一个程序。
但是,在这个过程中,涉及如下几个方面:

使用的编程语言 程序员需要选择一门或者多门语言来编程,不同的语言适合编写不同的程序,目前主流编程语言包括,Java、JavaScript、Python、C++、php以及其他小语种等等,每种编程语言适合开发的程序有所不同。目前从程序应用分来,主要可以分为三类a 企业应用,主要用于解决企业业务。各种企业管理后台系统,银行系统,公安系统,图书管理系统等等。
b 互联网应用,面向互联网用户,为互联网用户提供各类服务。比如现在的京东淘宝各类电商系统等。
c 移动应用,各类在移动端使用的APP,有面向互联网用户的APP,也有面向企业内部的APP。
目前相对而言,在移动应用和互联网应用方面,资本投入比较热的风口,程序员的薪资较高。企业应用,发展了很多年,相对平稳。

2. 明白需求,实现需求
需求就是编写程序的要求。一个程序要编写成什么样子,具备哪些功能,都是由需求来具体说明。程序员要需要能看懂需求文档,并且能准确地使用编程语言,根据需求中的要求来编写成程序。企业开发的项目,往往会由该程序的架构师提供一个程序框架,程序员在该框架的规范下进行编程,实现需求的功能,以确保程序的规范、可读,以及可维护性。

3. 日常工作写程序
一个软件开发一般流程是产品经理根据用户需求做一个项目出来,然后UI设计师做一些图片设计,前端开发编写页面,后台开发编写核心编程,然后介入一些大数据和人工智能,通过测试之类上线实施,后期还有运维进行相关维护。
程序员一般大多指的是前端和后台写代码程序的开发人员,除了编写代码,可能还需要通过接口和其它系统对接,实现系统间的数据交换。像单体测试,是程序员对自己写好的程序单元进行测试,检测这个程序单元数据输入和数据输出是否符合预期等等。测试出来的问题,需要修改正确,然后再测试,直至没有问题。和同事共同开发的时候也需要联合测试,以及用户测试过后如果存在BUG继续进行修改。

E. 简述程序设计的三种基本程序结构,其执行的条件和顺序

1、顺序结构:顺序结构是一种线性、有序的结构,它依次执行各语句模块。

2、循环结构:循环结构是重复执行一个或几个模块,直到满足某一条件为止。

3、选择结构:选择结构是根据条件成立与否选择程序执行的通路。

当型循环:表示先判断条件,当满足给定的条件时执行循环体,并且在循环终端处流程自动返回到循环入口;如果条件不满足,则退出循环体直接到达流程出口处。因为是"当条件满足时执行循环",即先判断后执行,所以称为当型循环。

(5)程序员代码重复执行扩展阅读:

注意事项

1、使用顺序、选择、循环等有限的基本结构表示程序逻辑。

2、选用的控制结构只准许有一个入口和一个出口

3、程序语句组成容易识别的块,每块只有一个入口和一个出口。

4、复杂结构应该用基本控制结构进行组合或嵌套来实现。

5、程序设计语言中没有的控制结构,可用一段等价的程序段模拟,但要求改程序段在整个系统中应前后一致。

6、严格控制GOTO语句。

阅读全文

与程序员代码重复执行相关的资料

热点内容
数控三通编程 浏览:298
linux多终端 浏览:811
法律写作pdf 浏览:144
国货哪个品牌最好app 浏览:951
看哪个app给钱最多 浏览:178
编程靠经验吗 浏览:759
c教程pdf下载地址 浏览:573
制作视频哪个app有瘦脸功能 浏览:649
linux查看线程内存 浏览:509
命令行签名apk 浏览:92
网页照片旋转源码 浏览:842
QQ会员头像源码 浏览:263
内核命令行 浏览:324
脚本提取源码器 浏览:930
smo源码 浏览:877
为什么要搭建单独服务器 浏览:480
编译器有什么控制 浏览:893
希尔伯特pdf 浏览:645
php数组全数字 浏览:647
解密塔罗牌小程序源码 浏览:862