Spring系列文章:Spring事务

2023-10-27

一、事务简述

1、什么是事务( Transaction(tx))

在⼀个业务流程当中,通常需要多条DML(insert delete update)语句共同联合才能完成,这 多条DML语句必须同时成功,或者同时失败,这样才能保证数据的安全。

多条DML要么同时成功,要么同时失败,这叫做事务。

2、事务的四个处理过程

第⼀步:开启事务 (start transaction)

第⼆步:执⾏核⼼业务代码

第三步:提交事务(如果核⼼业务处理过程中没有出现异常)(commit transaction)

第四步:回滚事务(如果核⼼业务处理过程中出现异常)(rollback transaction)

3、事务的四个特性:

A 原⼦性:事务是最⼩的⼯作单元,不可再分。

C ⼀致性:事务要求要么同时成功,要么同时失败。事务前和事务后的总量不变。

I 隔离性:事务和事务之间因为有隔离性,才可以保证互不⼲扰。

D 持久性:持久性是事务结束的标志

二、Spring事务

1、简述

Spring实现事务的两种⽅式

第一种:编程式事务

        事务功能的相关操作全部通过自己编写代码来实现:

第二种:声明式事务

既然事务控制的代码有规律可循,代码的结构基本是确定的,所以框架就可以将固定模式的代码抽取出 来,进行相关的封装。 封装起来后,我们只需要在配置文件中进行简单的配置即可完成操作。有基于注解⽅式 和基于XML配置⽅式

Spring对事务的管理底层实现⽅式是基于AOP实现的。采⽤AOP的⽅式进⾏了封装。所以Spring专⻔针 对事务开发了⼀套API,API的核⼼接⼝如下:

  • PlatformTransactionManager接⼝:spring事务管理器的核⼼接⼝。在Spring6中它有两个实现:
  • DataSourceTransactionManager:⽀持JdbcTemplate、MyBatis、Hibernate等事务管理。 JtaTransactionManager:⽀持分布式事务管理。

如果要在Spring6中使⽤JdbcTemplate,就要使⽤DataSourceTransactionManager来管理事务。 (Spring内置写好了,可以直接⽤。) 

2、编程式事务

事务功能的相关操作全部通过自己编写代码来实现:

Connection conn = ...;
try {
// 开启事务:关闭事务的自动提交
conn.setAutoCommit(false);
// 核心操作
// 提交事务
conn.commit();
}catch(Exception e){
// 回滚事务
conn.rollBack();
}finally{
// 释放数据库连接
conn.close();
}

编程式的实现方式存在缺陷:

细节没有被屏蔽:具体操作过程中,所有细节都需要程序员自己来完成,比较繁琐。

代码复用性不高:如果没有有效抽取出来,每次实现功能都需要自己编写代码,代码就没有得到复 用。 

3、声明式事务之注解方式

3.1、配置

依赖

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.1</version>
</dependency>
<!-- Spring 在执行持久化层操作、与持久化层技术进行整合过程中,需要使用orm、jdbc、tx三个
jar包,导入 orm 包就可以通过 Maven 的依赖传递性把其他两个也导入 -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-orm</artifactId>
    <version>5.3.1</version>
</dependency>

⼀定要集成Log4j2⽇志框架,在⽇志信息中可以看到更加详细的信息。

 jdbc配置文件

jdbc.user=root
jdbc.password=root
jdbc.url=jdbc:mysql://localhost:3306/ssm
jdbc.driver=com.mysql.cj.jdbc.Driver

spring配置文件

<!--扫描组件-->
<context:component-scan base-package="com.demo.spring.tx.annotation">
</context:component-scan>

<!-- 导入外部属性文件 -->
<context:property-placeholder location="classpath:jdbc.properties" />

<!-- 配置数据源 -->
<bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="url" value="${jdbc.url}"/>
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>

<!-- 配置 JdbcTemplate -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<!-- 装配数据源 -->
<property name="dataSource" ref="druidDataSource"/>
</bean>

<!-- 事务管理器 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>

<!--
开启事务的注解驱动
通过注解@Transactional所标识的方法或标识的类中所有的方法,都会被事务管理器管理事务
-->
<!-- transaction-manager属性的默认值是transactionManager,如果事务管理器bean的id正好就
是这个默认值,则可以省略这个属性 -->
<tx:annotation-driven transaction-manager="transactionManager" />

添加注解 

因为service层表示业务逻辑层,一个方法表示一个完成的功能,因此处理事务一般在service层添加注解@Transactional 

@Transactional标识在方法上,只会影响该方法

@Transactional标识的类上,会影响类中所有的方法

接口BookDao:

public interface BookDao {
Integer getPriceByBookId(Integer bookId);
void updateStock(Integer bookId);
void updateBalance(Integer userId, Integer price);
}

实现类BookDaoImpl:

@Repository
public class BookDaoImpl implements BookDao {
@Autowired
private JdbcTemplate jdbcTemplate;
@Override
public Integer getPriceByBookId(Integer bookId) {
String sql = "select price from t_book where book_id = ?";
return jdbcTemplate.queryForObject(sql, Integer.class, bookId);
}
@Override
public void updateStock(Integer bookId) {
String sql = "update t_book set stock = stock - 1 where book_id = ?";
jdbcTemplate.update(sql, bookId);
}
@Override
public void updateBalance(Integer userId, Integer price) {
String sql = "update t_user set balance = balance - ? where user_id =
?";
jdbcTemplate.update(sql, price, userId);
}
}

接口BookService:

public interface BookService {
void buyBook(Integer bookId, Integer userId);
}

实现类BookServiceImpl:

@Service
public class BookServiceImpl implements BookService {
@Autowired
private BookDao bookDao;

@Transactional
@Override
public void buyBook(Integer bookId, Integer userId) {
//查询图书的价格
Integer price = bookDao.getPriceByBookId(bookId);
//更新图书的库存
bookDao.updateStock(bookId);
//更新用户的余额
bookDao.updateBalance(userId, price);
}
}

3.2、事务属性

事务属性包括哪些

 事 务 中 的 重 点 属 性:

  • 事务传播⾏为
  • 事务隔离级别
  • 事务超时
  • 只读事务
  • 设置出现哪些异常 回 滚 事 务
  • 设 置 出 现 哪 些异常 不 回 滚 事 务
事务 传 播 ⾏ 为

什么是事务的传播⾏为? 在service类中有a()⽅法和b()⽅法,a()⽅法上有事务,b()⽅法上也有事务,当a()⽅法执⾏过程中调⽤了 b()⽅法,事务是如何传递的?合并到⼀个事务⾥?还是开启⼀个新的事务?这就是事务传播⾏为。

事务传播⾏为在spring框架中被定义为枚举类型:

 ⼀共有七种传播⾏为:

  • REQUIRED:⽀持当前事务,如果不存在就新建⼀个(默认)【没有就新建,有就加⼊】
  • SUPPORTS:⽀持当前事务,如果当前没有事务,就以⾮事务⽅式执⾏【有就加⼊,没有就不管 了】
  • MANDATORY:必须运⾏在⼀个事务中,如果当前没有事务正在发⽣,将抛出⼀个异常【有就 加⼊,没有就抛异常】
  • REQUIRES_NEW:开启⼀个新的事务,如果⼀个事务已经存在,则将这个存在的事务挂起 【不管有没有,直接开启⼀个新事务,开启的新事务和之前的事务不存在嵌套关系,之前事务 被挂起】
  • NOT_SUPPORTED:以⾮事务⽅式运⾏,如果有事务存在,挂起当前事务【不⽀持事务,存在 就挂起】
  • NEVER:以⾮事务⽅式运⾏,如果有事务存在,抛出异常【不⽀持事务,存在就抛异常】
  • NESTED:如果当前正有⼀个事务在进⾏中,则该⽅法应当运⾏在⼀个嵌套式事务中。被嵌套 的事务可以独⽴于外层事务进⾏提交或回滚。如果外层事务不存在,⾏为就像REQUIRED⼀ 样。【有事务的话,就在这个事务⾥再嵌套⼀个完全独⽴的事务,嵌套的事务可以独⽴的提交 和回滚。没有事务就和REQUIRED⼀样。】

在代码中设置事务的传播⾏为:

@Transactional(propagation = Propagation.REQUIRED)

 

事务隔离级别 

数据库系统必须具有隔离并发运行各个事务的能力,使它们不会相互影响,避免各种并发问题。一个事 务与其他事务隔离的程度称为隔离级别。

SQL标准中规定了多种事务隔离级别,不同隔离级别对应不同 的干扰程度,隔离级别越高,数据一致性就越好,但并发性越弱。

数据库中读取数据存在的三⼤问题:(三⼤读问题)

  • 脏读:读取到没有提交到数据库的数据,叫做脏读。
  • 不可重复读:在同⼀个事务当中,第⼀次和第⼆次读取的数据不⼀样。
  • 幻读:读到的数据是假的。

隔离级别一共有四种:

  • 读未提交:READ UNCOMMITTED、 允许Transaction01读取Transaction02未提交的修改。这种隔离级别,存在脏读问题,所谓的脏读(dirty read)表示能够读取到其它事务未提交的 数据
  • 读已提交:READ COMMITTED、 要求Transaction01只能读取Transaction02已提交的修改。解决了脏读问题,其它事务提交之后才能读到,但存在不可重复读问题。
  • 可重复读:REPEATABLE READ、 确保Transaction01可以多次从一个字段中读取到相同的值,即Transaction01执行期间禁止其它 事务对这个字段进行更新。解决了不可重复读,可以达到可重复读效果,只要当前事务不结束,读取到的数据⼀直都 是⼀样的。但存在幻读问题。
  • 串行化:SERIALIZABLE 、确保Transaction01可以多次从一个表中读取到相同的行,在Transaction01执行期间,禁止其它 事务对这个表进行添加、更新、删除操作。可以避免任何并发问题,但性能十分低下。解决了幻读问题,事务排队执⾏。不⽀持并发。

各个隔离级别解决并发问题的能力

各种数据库产品对事务隔离级别的支持程度

使用,隔离级别在spring中以枚举类型存在:

代码使用

@Transactional(isolation = Isolation.DEFAULT)//使用数据库默认的隔离级别
@Transactional(isolation = Isolation.READ_UNCOMMITTED)//读未提交
@Transactional(isolation = Isolation.READ_COMMITTED)//读已提交
@Transactional(isolation = Isolation.REPEATABLE_READ)//可重复读
@Transactional(isolation = Isolation.SERIALIZABLE)//串行化

只读

对一个查询操作来说,如果我们把它设置成只读,就能够明确告诉数据库,这个操作不涉及写操作。这 样数据库就能够针对查询操作来进行优化。

@Transactional(readOnly = true)
public void buyBook(Integer bookId, Integer userId) {
//查询图书的价格
Integer price = bookDao.getPriceByBookId(bookId);
//更新图书的库存
bookDao.updateStock(bookId);
//更新用户的余额
bookDao.updateBalance(userId, price);
//System.out.println(1/0);
}

对增删改操作设置只读会抛出下面异常: Caused by: java.sql.SQLException: Connection is read-only. Queries leading to data modification are not allowed 

该特性的作⽤是:启动spring的优化策略。提⾼select语句执⾏效率。

如果该事务中确实没有增删改操作,建议设置为只读事务

超时

事务在执行过程中,有可能因为遇到某些问题,导致程序卡住,从而长时间占用数据库资源。而长时间 占用资源,大概率是因为程序运行出现了问题(可能是Java程序或MySQL数据库或网络连接等等)。

此时这个很可能出问题的程序应该被回滚,撤销它已做的操作,事务结束,把资源让出来,让其他正常 程序可以执行。

概括来说就是一句话:超时回滚,释放资源。

@Transactional(timeout = 3)
public void buyBook(Integer bookId, Integer userId) {
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
//查询图书的价格
Integer price = bookDao.getPriceByBookId(bookId);
//更新图书的库存
bookDao.updateStock(bookId);
//更新用户的余额
bookDao.updateBalance(userId, price);
//System.out.println(1/0);
}

执行过程中抛出异常: org.springframework.transaction.TransactionTimedOutException

以上代码表示设置事务的超时时间为3秒。 表示超过3秒如果该事务中所有的DML语句还没有执⾏完毕的话,最终结果会选择回滚。

默认值-1,表示没有时间限制。

这⾥有个坑,事务的超时时间指的是哪段时间? 在当前事务当中,最后⼀条DML语句执⾏之前的时间。如果最后⼀条DML语句后⾯很有很多业务逻辑, 这些业务代码执⾏的时间不被计⼊超时时间。

以下代码的超时不会被计⼊超时时间

@Transactional(timeout = 10) // 设置事务超时时间为10秒。
public void save(Account act) {
 accountDao.insert(act);
 // 睡眠⼀会
 try {
 Thread.sleep(1000 * 15);
 } catch (InterruptedException e) {
 e.printStackTrace();
 }
}

当然,如果想让整个⽅法的所有代码都计⼊超时时间的话,可以在⽅法最后⼀⾏添加⼀⾏⽆关紧要的 DML语句。 

设置哪些异常回滚事务、哪些异常不回滚事务

声明式事务默认只针对运行时异常回滚,编译时异常不回滚。 可以通过@Transactional中相关属性设置回滚策略

rollbackFor属性:需要设置一个Class类型的对象

rollbackForClassName属性:需要设置一个字符串类型的全类名

noRollbackFor属性:需要设置一个Class类型的对象

rollbackFor属性:需要设置一个字符串类型的全类名

@Transactional(noRollbackFor = ArithmeticException.class)
//@Transactional(noRollbackForClassName = "java.lang.ArithmeticException")
public void buyBook(Integer bookId, Integer userId) {
//查询图书的价格
Integer price = bookDao.getPriceByBookId(bookId);
//更新图书的库存
bookDao.updateStock(bookId);
//更新用户的余额
bookDao.updateBalance(userId, price);
System.out.println(1/0);
}

虽然购买图书功能中出现了数学运算异常(ArithmeticException),但是我们设置的回滚策略是,当 出现ArithmeticException不发生回滚,因此购买图书的操作正常执行 

表示只有发⽣RuntimeException异常或该异常的⼦类异常才回滚。

@Transactional(rollbackFor = RuntimeException.class)

3.3、 事务的全注解式开发

编写⼀个类来代替配置⽂件,代码如下:

@Configuration
@ComponentScan("com.demo.bank")
@EnableTransactionManagement
public class Spring6Config {
    @Bean
    public DataSource getDataSource(){
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/spring6");
        dataSource.setUsername("root");
        dataSource.setPassword("root");
        return dataSource;
    }
    @Bean(name = "jdbcTemplate")
    public JdbcTemplate getJdbcTemplate(DataSource dataSource){
        JdbcTemplate jdbcTemplate = new JdbcTemplate();
        jdbcTemplate.setDataSource(dataSource);
        return jdbcTemplate;
    }
    @Bean
    public DataSourceTransactionManager getDataSourceTransactionManager(DataSource dataSource){
        DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
        dataSourceTransactionManager.setDataSource(dataSource);
        return dataSourceTransactionManager;
    }
}

4、声明式事务之xml方式

基于xml实现的声明式事务,必须引入aspectJ的依赖

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.3.1</version>
</dependency>

applicationContext.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:tx="http://www.springframework.org/schema/tx"
       xmlns:aop="http://www.springframework.org/schema/aop"
       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:component-scan base-package="com.demo"/>

    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/spring6"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
    </bean>

    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!--配置事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!--配置通知-->
    <!-- id属性:给事务通知标签设置唯一标识,便于引用 -->
    <!-- transaction-manager属性:关联事务管理器 -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <!-- tx:method标签:配置具体的事务方法 -->
            <!-- name属性:指定方法名,可以使用星号代表多个字符 -->
            <tx:method name="get*" read-only="true"/>
            <tx:method name="query*" read-only="true"/>
            <tx:method name="find*" read-only="true"/>
            <!-- read-only属性:设置只读属性 -->
            <!-- rollback-for属性:设置回滚的异常 -->
            <!-- no-rollback-for属性:设置不回滚的异常 -->
            <!-- isolation属性:设置事务的隔离级别 -->
            <!-- timeout属性:设置事务的超时属性 -->
            <!-- propagation属性:设置事务的传播行为 -->
            <tx:method name="save*" propagation="REQUIRED"   read-only="false" rollback-for="java.lang.Throwable"/>
            <tx:method name="del*" propagation="REQUIRED"  read-only="false" rollback-for="java.lang.Throwable"/>
            <tx:method name="update*" propagation="REQUIRED"  read-only="false" rollback-for="java.lang.Throwable"/>
            <tx:method name="transfer*" propagation="REQUIRED"  read-only="false" rollback-for="java.lang.Throwable"/>
        </tx:attributes>
    </tx:advice>

    <!--配置切⾯-->
    <aop:config>
        <aop:pointcut id="txPointcut" expression="execution(* com.demo.service..*(..))"/>
        <!--切⾯ = 通知 + 切点-->
        <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/>
    </aop:config>
</beans>

事务注解 @Transactional 失效的3种场景及解决办法

事务注解 @Transactional 失效的3种场景及解决办法_Hollis Chuang的博客-CSDN博客

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spring系列文章:Spring事务 的相关文章

  • 如何将Android模拟器连接回ADB?

    当我通过在 Eclipse 中点击 调试 启动模拟器后 经过一定时间后它会与 ADB 断开连接 但模拟器保持打开状态 它反应灵敏 我可以导航和启动应用程序 如何将模拟器连接回 ADB 以便能够从 Eclipse 进行调试 当前的解决方法是终
  • 如何停止 adb 端口转发?

    可以转发端口adb forward tcp 8080 tcp 8080 但是我需要终止 adb 服务器来停止此转发吗 我正在寻找一种方法来停止 adb 中端口的转发 在设置之后 但不再需要转发时 Try adb forward remove
  • 一段时间后 Adb 停止检测我的手机

    我正在 Linux 机器上为 android 开发 并且我已经创建了一个udevandroid 规则并且它有效 一段时间后 如果我拔掉设备并再次插入 adb如果我运行则无法识别该设备lusb or dmesg获取有关设备的信息 我尝试重新加
  • Windows 8 上的 Firefox 远程调试“意外错误”

    我需要在 Firefox 中调试 Android 的 Web 应用程序 我尝试将设备连接到桌面版 Firefox 但总是收到错误 意外错误 我已经执行了所有步骤https developer mozilla org en US docs T
  • 使用 adb 刷新 Android mediastore

    我正在使用 adb 在 Android 手机上同步音乐 本质上 我管理现有的音乐目录并推送替换音乐文件 我希望能够使用 adb 强制重新扫描 以便谷歌音乐播放器 和其他应用程序 能够与新歌曲和播放列表正常工作 根据如何刷新 Android
  • adb 已停止在 android studio 中工作

    我正在尝试在 android studio 中构建我的第一个应用程序并收到错误 adb exe 已停止工作 我正在Windows xp 32位系统上工作 Have tried several solutions available onli
  • Adb安装进度条

    我是这方面的初学者 所以如果我问任何明显的问题 请介意我 我正在尝试安装一个apk到我的设备使用adb install apk apk但是 那apk大约有几百 MB 大 并且需要一些时间 我可以在命令窗口中实现某种进度条来显示进度吗 我见过
  • ADB Shell 输入事件

    之间的基本区别是什么adb shell input keyevent and adb shell sendevent 我应该使用哪一个来输入字符 我们传递给这两个命令的键码是否相同 By adb shell input keyevent 或
  • java.lang.SecurityException:权限拒绝:启动意图 { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER]

    启动时出错activity 不幸的是 我认为它与该项目没有严格联系 因为该应用程序启动于genymotion模拟器 但不在物理设备上 当我跑步时adb devices与真实的连接后我得到 List of devices attached 0
  • 安装apk时INSTALL_FAILED_NO_MATCHING_ABIS

    我尝试将我的应用程序安装到 Android L Preview Intel Atom 虚拟设备中 但失败并出现错误 INSTALL FAILED NO MATCHING ABIS 这是什么意思 INSTALL FAILED NO MATCH
  • 即使在模拟器上,“adb root”命令也会返回“adbd 无法在生产版本中以 root 身份运行”?

    我正在尝试运行adb root模拟器上的命令 这是我连接的唯一设备 adb devices List of devices attached emulator 5554 device 但是 我收到以下错误消息 adb root adbd c
  • 启动后台进程时ADB进程阻塞

    我正在尝试通过 ADB 在 Android 手机后台运行 shell 脚本 为了简单起见 我们让它睡眠 100 adb shell echo nohup sleep 100 gt data local tmp test sh sh data
  • 未找到 ADB screenrecord 命令

    我无法奔跑adb shell screenrecord sdcard my mp4 我尝试运行此命令的设备规格 Honor 5C 安卓6 0 每当我运行 screenrecord 命令时 它都会显示未找到命令 D adb gt adb sh
  • Visual Studio 不允许我在 Android 物理设备上进行调试

    我正在使用 Xamarin 和 Visual Studio 2013 开发 Android 应用程序 我已将 Android 小程序连接到计算机 Sansung Kies 识别了该设备 Adb 也能识别它 因为当我输入 adb device
  • ADB TCPIP 连接问题

    我有两台 Galaxy S3 其中一个已扎根 另一个则未扎根 因此 当我尝试通过本地网络连接它们时 计算机可以看到已root的计算机 但是正常的就卡在tcpip这一步了 所以 我写 adb tcpip 5555 It says restar
  • adb 今天无法连接到 VirtualBox 中的 Android-x86

    我在 VirtualBox 中成功安装了 Android x86 v3 2 eeepc 一段时间 这是帮助我在 Android 上调试 USB 主机应用程序的好方法 此类配置的安装是 安装VirtualBox 将 Android x86 v
  • 是否可以从应用程序执行 ADB shell 命令?

    我有一个安卓电脑 http www timingpower com rk3288 with root 开箱即用 连接到始终以横向显示的外部显示器 HDMI 和 USB 即使我的应用程序在清单中的活动声明中指定纵向 android scree
  • 为什么 adb install 失败? [复制]

    这个问题在这里已经有答案了 我知道adb install如果现有包具有不同的版本 则不会替换它type 即调试与发布 每当我运行调试会话时 Eclipse 也会成功替换调试 apk 但是当我尝试adb install用于替换现有的relea
  • 如何在android中的/system/etc/permissions内添加android.hardware.usb.host.xml

    我在手机上进行了备份恢复Cherry Mobile Infinix Pure XL Model X210 我发现USB OTG不管用 所以我看一下permissions文件夹 参考 Youtube 视频 https www youtube
  • 如何更改终端的默认目录?

    我想更改 Android Studio v2 2 2 终端的默认目录 当我打开终端时 它基于项目的目录 C 项目路径 我经常需要使用adb shell 所以我必须导航到 SDK 路径 平台工具 才能使用 adb 命令 是否可以更改终端的默认

随机推荐

  • Mysql——使用字符集以及校对

    一 字符集 1 查看mysql支持的所有字符集 show character set 2 查看指定数据库的字符集 show variables like character 这八种情况分别对应 1 设置客户端使用的字符集 2 设置链接数据库
  • 如何将vscode设置成中文字体

    场景 最近不知道怎么的 vscode总是会自动跳回英文字体 明明已经下载过中文的字体了 解决方案 快捷键
  • PID调参过程详解(包括增量式和位移式)

    转载于https blog csdn net wangweijundeqq article details 76389770 位置闭环控制就是根据编码器的脉冲累加测量电机的位置信息 并与目标预设值做比较 得到控制偏差 然后通过对偏差的P比例
  • 容器查看与删除

    lcc lcc docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ad424be7a46b mysql docker entrypoint s About an
  • 部分手机拍照屏幕旋转, 导致imageview不能显示的问题???

    在项目开发的过程中 碰见了一个非常诡异的事情 拍照之后的imageview不能正常显示图片 从而导致十行代码中间的几句代码不执行 不执行 不执行 代码中包括imageview setImageBitmap bitmap 一度认为这个bitm
  • Leetcode_146. LRU 缓存

    C语言纯暴力解法 能AC我没想到 typedef struct int key int val int time LRUCache int g cap 全局变量记录缓存容量 int g time 利用全局变量更新put和get操作时关键值的
  • 常见的服务器部署SSL证书的安装方法介绍

    很多网络管理员对于SSL证书安装还是处于一个比较懵懂的状态 不同的服务器部署SSL证书方法也不一样 但是步骤确是类似的 生成证书请求文件 CRS 向CA机构申请SSL证书 下载证书 然后根据不同的系统安装部署SSL证书 最后测试证书 下面根
  • Windows下 flex + bison 小例子

    下载flex和bison 网址是http gnuwin32 sourceforge net packages flex htm 和http gnuwin32 sourceforge net packages bison htm 如果这两个链
  • MySQL数据库的安装、创建库、创建表、向数据库添加测试数据及连接取数、遍历输出数据库查询结果ResultSet、使用“Class.forName(JDBC_DRIVER);”来注册加载驱动的原因

    MySQL数据库的安装 创建库 创建表 向数据库添加测试数据及连接取数 MySQL数据库简介 Java对于数据库常用操作的封装 安装MySQL数据库 下载MySQL安装包 Linux MySQL在ubuntu Linux下的多版本选择 DE
  • linux学习笔记7(PHP安装)

    49 安装PHP PHP PHP Hypertext Preprocessor 即 超文本预处理器 是在服务器端执行的脚本语言 尤其适用于Web开发并可嵌入HTML中 PHP语法学习了C语言 吸纳Java和Perl多个语言的特色发展出自己的
  • kettle使用常见问题解决-01

    kettle常见问题解决 1 kettle界面connect消失 第一步 检查IE浏览器 不能低于10 第二步 在数据资源仓库的database里描述写中文 导致repositories xml出现乱码 解决方法 1 找到 kettle目录
  • ant design pro 一个页面两个表单,提交会相互影响,需将表单写为自定义组件

    描述 在页面 组件 中 只能有一个 Form create 意味着this props form唯一 如果一个页面有两个表单 提交其中一个 另一个也会提交 然而你只想提交一个 解决方法 1 如果表单多且复杂 请单独自定义一个页面 组件 我这
  • 了解Hadoop输入输出系统

    与任何I O子系统不同 Hadoop还带有一组原语 这些原始的考虑因素虽然本质上是通用的 但与Hadoop IO系统一起也具有一些特殊的含义 Hadoop处理数TB的数据集 对这些原语的特殊考虑将使你了解Hadoop如何处理数据输入和输出
  • 华为、腾讯、阿里、网易员工下班时间大曝光,靠加班,你是赢不了他们的

    这年头 不加班都不好意思说自己是上班族的 但有一种行业的疯狂加班程度 已经逐渐成为加班领域的一颗新星 那就是 互联网行业从事者 也许你对华为 阿里的加班水平早有耳闻 但你是否见过他们疯狂加班的样子呢 首先出场的阿里巴巴 19 55 00 0
  • 生成10个随机数保存于数组中,并找出其最大值和最小值

    上代码吧 bin bash 生成19个随机数保存于数组中 并找出其最大值和最小值 declare a rand declare i max min for i in 0 9 do rand i RANDOM echo rand i if i
  • CTFHUB-WEB

    HTTP协议 题目 请求方式 思路一 我们知道http请求方式中没有CTFB方式 就想到CTFHUB 使用BP抓包 将原来的数据包请求方式GET改成CTFHUB 点击Forward 放包 得到flag 积累 HTTP协议的八种请求方式 1
  • 典型案例 3:十分钟搭建弹性可扩展的 Web API

    作者 萧起 阿里云云原生团队 导读 本节课程主要分为三个部分 基本概念中介绍基于函数计算的 WebAPI 与普通的 WebAPI 的区别及优势 开发流程中介绍如何在函数计算的控制台进行 WebAPI 的开发 操作演示中会实例演示函数计算 W
  • mysql-索引_MySQL-索引

    mysql 索引 MySQL 索引 MySQL INDEXES A database index is a data structure that improves the speed of operations in a table In
  • 基于MATLAB的图像复原视图分析技术

    基于MATLAB的图像复原视图分析技术 摘要 图像质量的好与坏受很多方面因素的影响 其中运动模糊以及失真是较为主要的因素 这些因素贯穿在图像获取 传输以及储存的全过程中 本次设计用到的是MATLAB软件然后进行仿真 对模糊图像建立退化模型
  • Spring系列文章:Spring事务

    一 事务简述 1 什么是事务 Transaction tx 在 个业务流程当中 通常需要多条DML insert delete update 语句共同联合才能完成 这 多条DML语句必须同时成功 或者同时失败 这样才能保证数据的安全 多条D