关于数据库的部分知识

数据库引擎:

在这里插入图片描述
默认使用:Innodb

如何更改默认数据库引擎

找到MySQL配置文件mysql.ini,首先将其备份(这是个好习惯,当需要更改Linux上配置文件时)即

cp mysql.ini mysql.ini.bak
如何在建表时设置引擎及建表后更改引擎

建表时设置引擎:

create table 表名(

)ENGINE=引擎名

事物

事物是指逻辑上的一组操作,组成这组操作的各个单元,要么全部执行成功,要么全部实行失败。

事务 的基本原理

1、不用事务,直接作用于表
在这里插入图片描述
2、用了事务之后
在这里插入图片描述
例如:张三–李四转账
– 事物
CREATE TABLE account(
id INT PRIMARY KEY auto_increment,
name VARCHAR(10),
money DOUBLE
);
INSERT INTO account(name,money) VALUES(‘张三’,1000),(‘李四’,1000);
– 张三给李四转账1000块钱
UPDATE account SET money=money-1000 WHERE name=‘张三’;
UPDATE account SET money=money+1000 WHERE name=‘李四’;

数据库开启事务的命令:
Connection接口下面的方法:
void setAutoCommit(boolean autoCommit);autoCommit - 为 true 表示启用自动提交模式;为 false 表示禁用自动提交模式(默认情况下就是true)(可以用这个来防止转账失败但是仍然修改金额的发生)
void commit();手动提交事物。
void rollback();回滚(出现异常的时候,所有已经执行成功的代码需要回退到事务开始前的状态)
默认情况下,Connetion对象处于自动提交模式下,这意味着他在执行每个语句后都会自动提交更改。
如果禁用自动提交模式,那么提交更改就必须显示调用commit方法,否则就无法保存数据库的更改。

public void test1() {
   Connection connection = null;
   PreparedStatement preparedStatement = null;
   String sql1 = "UPDATE account SET money=money-1000 WHERE name='张三'";
   String sql2 = "UPDATE account SET money=money+1000 WHERE name='李四'";
   try {
      connection = JDBCUtil.getConnection();
      
      // 为false,表示禁用自动提交(默认情况是true)
      connection.setAutoCommit(false);
      
      preparedStatement = connection.prepareStatement(sql1);
      System.out.println(preparedStatement);
      preparedStatement.executeUpdate();
      
      // ArithmeticException: / by zero
      int i = 3 / 0;
      
      preparedStatement = connection.prepareStatement(sql2);
      System.out.println(preparedStatement);
      preparedStatement.executeUpdate();
      
      // setAutoCommit(false)改成false之后,不会提交数据库,只有调用connection.commit()才提交
      connection.commit();
   } catch (SQLException e) {
      e.printStackTrace();
      try {
         connection.rollback();
      } catch (SQLException e1) {
         e1.printStackTrace();
      }
   } finally {
      JDBCUtil.close(connection, preparedStatement, null);
   }
   
}

事务四个基本特征或 ACID 特性:

1、Atomicity(原子性):一个事务(transaction)中的所有操作,或者全部完成,或者全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。即,事务不可分割、不可约简。
2、Consistency(一致性):在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设约束、触发器、级联回滚等。
3、Isolation(隔离性):数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务concurrent并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括未提交读(Read uncommitted)、提交读(read committed)、可重复读(repeatable read)和串行化(Serializable)。
4、Durability(持久性):事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。

Spring的事物传播特性(属性)

当事务方法被另一个事务方法调用时,必须指定事务应该如何传播。例如:一个方法运行在了一个开启了事务的方法中时,当前方法是使用原来的事务还是开启一个新的事务。
Spring定义了7种类传播行为:
Propagation:
PROPAGATION_REQUIRED:需要, 如果存在一个事务,则支持当前事务, 如果没有事务则开启(原来有就使用原来事物,没有就创建事物,一般Service的中更新类的操作)
PROPAGATION_SUPPORTS:支持, 如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行(原来有就使用原来事物,没有就算了,一般Service的中查询操作)
PROPAGATION_REQUIRES_NEW:总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起。
PROPAGATION_MANDATORY: 必要的 如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常。
PROPAGATION_NOT_SUPPORTED:总是非事务地执行,并挂起任何存在的事务。
PROPAGATION_NEVER:绝不 总是非事务地执行,如果存在一个活动事务,则抛出异常
PROPAGATION_NESTED:嵌套的 如果有就嵌套、没有就开启事务

事务传播属性可以在@Transactional注解的propagation属性中定义。
在这里插入图片描述

数据库事务并发Concurrent问题

1、脏读

(当前事物读到了其他事物更新但是还没有提交的值就是脏读)①Transaction01将某条记录的AGE值从20修改为30。②Transaction02读取了Transaction01更新后的值:30。Read Uncommited③Transaction01回滚,AGE值恢复到了20。④Transaction02读取到的30就是一个无效的值。
只有脏读是读取了别人更新但是还没有提交到数据库的数据,不可重复读和幻读都是读取已经提交数据库的数据。

2、不可重复读

unrepeatable read
①Transaction01读取了AGE值为20。
②Transaction02将AGE值修改为30,提交数据库。
③Transaction01再次读取AGE值为30,和第一次读取的不一样
这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。

3、幻读

①Transaction01读取了Student表中的一部分数据
②Transaction02向Student表中插入了新的行
③Transaction01读取了Student表时,多出了一些行。

事物隔离级别 isolate

数据库系统必须具有隔离并发运行各个事务的能力,使它们不会相互影响,避免各种并发问题。
隔离级别越高,数据一致性就越好,但并发性越弱。
1、读未提交:READ UNCOMMITTED
  允许Transaction01读取Transaction02未提交的修改。
2、读已提交:READ COMMITTED
  要求Transaction01只能读取Transaction02已提交的修改。
3、可重复读:REPEATABLE READ
确保Transaction01可以多次从一个字段中读取到相同的值,即Transaction01执行期间禁止其它事务对这个字段进行更新。
4、串行化:SERIALIZABLE
  确保Transaction01可以多次从一个表中读取到相同的行,在Transaction01执行期间,禁止其它事务对这个表进行添加、更新、删除操作。可以避免任何并发问题,但性能十分低下。(单线程,在一个请求中,其他线程读都不可以)
  在这里插入图片描述可以在@Transactional的isolation属性中设置隔离级别,并不是隔离级别越高越好,一般是READ COMMITTED读已提交。

Isolation.REPEATABLE_READ:可重复读,MySQL默认的隔离级别
Isolation.READ_COMMITTED:读已提交,Oracle默认的隔离级别,开发时通常使用的隔离级别

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值