MySQL事务

事务的特性(ACID)

  • Atomicity 原子性
    • 事务中的一组操作,要么全部成功,要么全部失败。
    • 事务的原子性通过undo日志实现
  • Consistency 一致性
    • 事务开始前和结束后,数据库的完整性没有被破坏。比如:A向B转账,不能A扣款成功,而B没有收到。
  • Isolation 隔离性
    • 多个事务并发执行时,事务之间不会互相影响。
    • 事务的隔离行由MVCC机制保证。
  • Durability 持久性
    • 事务一旦提交,对数据库的变更就是永久的。
    • 事务的永久性通过redo日志实现

MySQL事务隔离级别

  • 读未提交

最低的隔离级别,允许事务读取其他事务已修改但尚未提交的数据

  • 读已提交=>常用的隔离级别

允许事务读取其他事务已提交的数据,可以避免脏读

正常来讲,事务之间应该互不干扰,该级别允许在当前事务中读取其他事务已经修改并提交的数据

  • 可重复读 InnoDB 存储引擎的默认支持的隔离级别=>常用的隔离级别

事务中对同一字段在不同时刻读取的结果都一致,可以避免脏读和不可重复读

事务开始后第一条查询语句执行时,数据库生成所有表数据的快照数据,后续该事务中所有查询都查询的快照数据,而非数据库最新数据。
除非该事务中对某条数据做了更新操作,那么后续查询到的就是数据库更新后的值
不能解决幻读问题:如果在事务A中对事务B提交的新增数据进行更新操作,那么下次查询就可以查询到该数据

  • 可串行化

最高的隔离级别,所有事务都依次执行,可以避免脏读、不可重复读和幻读

对于同一行记录,读会加读锁,写会加写锁,当出现读写冲突时,后一个事务必须等前一个事务结束

如何选择隔离级别

并发要求高的,选择 读已提交
对数据统一要求高的,选择 可重复读
因为隔离级别越高,并发性能越低

并发事务带来的问题

  • 脏读
    事务A读取到了事务B已修改未提交的数据
    事务B中修改了数据,但事务还未提交,此时事务A就查询到了修改后的数据
  • 不可重复读主要是针对更新和删除操作
    事务内部相同语句在不同时刻读取到的值不同
    例:
    隔离级别为 读已提交 时,
    ①事务A第一次查询到的数值为5000,
    ②事务B修改数值为4500,
    ③事务A查询到的数值为5000(没有出现脏读),
    ④事务B提交事务,
    ⑤事务A再次查询到的数值就是4500,与前两次查询到的数值不同
  • 幻读主要是针对插入操作

事务A读取到了事务B已提交的数据

首先来看看 MySQL 文档是怎么定义幻读(Phantom Read)的:
The so-called phantom problem occurs within a transaction when the same query produces different sets of rows at different times. For example, if a SELECT is executed twice, but returns a row the second time that was not returned the first time, the row is a “phantom” row.
翻译:当同一个查询在不同的时间产生不同的结果集时,事务中就会出现所谓的幻象问题。例如,如果 SELECT 执行了两次,但第二次返回了第一次没有返回的行,则该行是“幻像”行。

例:
隔离级别设置为 读已提交
①事务A按条件查询到一条数据
②事务B插入一条数据,并提交
③事务A再次查询,查到两条数据
若此时事务B回滚,那么之前事务A查到的两条数据就像幻觉一样

SQL 脚本 1 在第一次查询工资为 500 的记录时只有一条,SQL 脚本 2 插入了一条工资为 500 的记录,提交之后;SQL 脚本 1 在同一个事务中再次使用当前读查询发现出现了两条工资为 500 的记录这种就是幻读。

解决幻读的方法

解决幻读的方式有很多,但是它们的核心思想就是一个事务在操作某张表数据的时候,另外一个事务不允许新增或者删除这张表中的数据了。

解决幻读的方式主要有以下几种:
1. 将事务隔离级别调整为 SERIALIZABLE
2. 在可重复读的事务级别下,给事务操作的这张表添加表锁。
3. 在可重复读的事务级别下,给事务操作的这张表添加 Next-key Lock(Record Lock+Gap Lock)。

  • 脏写(更新丢失)读未提交、读已提交、可重复读 这3种隔离级别都不能解决脏写问题串行化可以解决吗??
    事务B修改了事务A已修改未提交的数据
    多个事务更新同一条数据,可能发生更新丢失
    ①事务A更新了一条数据
    ②事务B也更新了这条数据
    ③事务A回滚,把该数据回滚到之前的值,导致事务B的更新丢失
    **解决脏写的主要方式:**不要在java代码中对数据进行计算,而是通过sql语句执行计算

MySQL 命令行的默认配置中事务都是自动提交的,即执行 SQL 语句后就会马上执行 COMMIT 操作。如果要显式地开启一个事务需要使用命令:

START TRANSACTION。

我们可以通过下面的命令来设置隔离级别

SET [SESSION|GLOBAL] TRANSACTION ISOLATION LEVEL [READ UNCOMMITTED|READ COMMITTED|REPEATABLE READ|SERIALIZABLE]

我们再来看一下我们在下面实际操作中使用到的一些并发控制语句:

  • START TRANSACTION |BEGIN:显式地开启一个事务。
  • COMMIT:提交事务,使得对数据库做的所有修改成为永久性。
  • ROLLBACK:回滚会结束用户的事务,并撤销正在进行的所有未提交的修改。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
关于mysql事务处理 public static void StartTransaction(Connection con, String[] sqls) throws Exception { if (sqls == null) { return; } Statement sm = null; try { // 事务开始 System.out.println("事务处理开始!"); con.setAutoCommit(false); // 设置连接不自动提交,即用该连接进行的操作都不更新到数据库 sm = con.createStatement(); // 创建Statement对象 //依次执行传入的SQL语句 for (int i = 0; i < sqls.length; i++) { sm.execute(sqls[i]);// 执行添加事物的语句 } System.out.println("提交事务处理!"); con.commit(); // 提交给数据库处理 System.out.println("事务处理结束!"); // 事务结束 //捕获执行SQL语句组中的异常 } catch (SQLException e) { try { System.out.println("事务执行失败,进行回滚!\n"); con.rollback(); // 若前面某条语句出现异常时,进行回滚,取消前面执行的所有操作 } catch (SQLException e1) { e1.printStackTrace(); } } finally { sm.close(); } } 通常都是上述的写法, 在mysql 不支持事务的时候 , 中间的 setAutoCommit 的事务操作是不是都不生效. 现在innoDB支持 事务了, 上述的 java 代码是否能实现 以下的 事务隔离的 操作, 在修改的时候处于锁定状态 或者 只可以通过存储过程来实现, 单行的锁定 BEGIN; SELECT book_number FROM book WHERE book_id = 123 FOR UPDATE; --这里for update , 以前用Oracle的时候也是有这个行锁 // ... UPDATE book SET book_number = book_number - 1 WHERE book_id = 123; COMMIT;
MySQL 事务是指一组数据库操作,这些操作要么全部执行,要么全部不执行,其目的是保证在并发环境下,数据的一致性和完整性。MySQL 事务具有 ACID 性质,即原子性、一致性、隔离性和持久性。 MySQL 中使用事务需要使用 BEGIN、COMMIT 和 ROLLBACK 语句,其中 BEGIN 表示开启一个事务,COMMIT 表示提交事务,ROLLBACK 表示回滚事务事务的基本语法如下: ``` BEGIN; -- 执行一组数据库操作 COMMIT; -- 提交事务 -- 或者 ROLLBACK; -- 回滚事务 ``` 在 MySQL 中,事务的隔离级别分为四个等级,分别是 Read Uncommitted、Read Committed、Repeatable Read 和 Serializable。隔离级别越高,数据的一致性和完整性越高,但同时也会影响数据库的性能。 MySQL 事务的 ACID 性质有以下含义: 1. 原子性(Atomicity):事务中的所有操作要么全部执行成功,要么全部失败回滚,不会只执行其中的一部分操作。 2. 一致性(Consistency):事务执行前后,数据库中的数据必须保持一致性状态,即满足数据库的约束条件和完整性规则。 3. 隔离性(Isolation):事务之间应该是相互隔离的,一个事务的执行不应该被其他事务干扰,保证事务之间的数据相互独立。 4. 持久性(Durability):事务提交后,对数据库的修改应该是永久性的,即使出现系统故障或电源故障,也不应该对数据产生影响。 总之,MySQL 事务是一组数据库操作,具有 ACID 性质,可以通过 BEGIN、COMMIT 和 ROLLBACK 语句来实现,隔离级别越高,数据的一致性和完整性越高,但同时也会影响数据库的性能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值