MySQL中数据库事务实践与锁详解

一文读懂Spring事务和MySQL事务与锁

在数据库中,所谓事务是指一组逻辑操作单元,使数据从一种状态变换到另一种状态。

为确保数据库中数据的一致性,数据的操纵应当是离散的成组的逻辑单元。当它全部完成时,数据的一致性可以保持,而当这个单元中的一部分操作失败,整个事务应全部视为错误,所有从起始点以后的操作应全部回退到开始状态。

事务的操作

先定义开始一个事务,然后对数据作修改操作,这时如果提交(COMMIT),这些修改就永久地保存下来,如果回退(ROLLBACK),数据库管理系统将放弃所作的所有修改而回到开始事务时的状态。

【1】事务简介

事务:transaction,一系列要发生的操作;事务安全:一种保护连续操作同时满足(实现)的一种机制。事务安全的意义在于保证数据操作的完整性。只有InnoDB和BDB支持事务安全机制,其他不支持。

事务操作过程中,会触发MySQL的锁机制。InnoDB默认是行锁,但是如果在事务操作过程中,没有用到索引,那么系统会自动全表检索数据,自动升级为表锁。

行锁:只有当前行被锁住,别的用户不能操作。

表锁:整个表被锁住,别的用户不能操作。

事务类别

事务分为显示事务和隐式事务

显示事务

显式事务,事务具有明显的开启和结束的标记,需要注意的是必须先设置自动提交功能为禁用。set autocommit=0;

步骤1:开启事务
set autocommit=0;
start transaction;可选的
步骤2:编写事务中的sql语句(select insert update delete)
语句1;
语句2;
...

步骤3:结束事务
commit;提交事务
rollback;回滚事务

隐式事务

隐式事务,事务没有明显的开启和结束的标记,比如insert、update、delete语句。

【2】显示事务操作

① 开始事务

set autocommit=0;
start transaction;

告诉系统内以下所有操作(写)不要直接写入数据库,先存放到事务日志。

② 事务操作

示例如下(张三还钱1000给李四):


UPDATE my_account set money = money-1000 where id = 1;

select * from my_account

初始值:
这里写图片描述
还钱后:
这里写图片描述

此时李四并未收到money,断开链接(事务中断,并未commit),再次链接查询:

select * from my_account

这里写图片描述

张三账户还是1000,说明事务的有效性。

继续事务操作:

UPDATE my_account set money = money+1000 where id = 2;

如果在提交前断开链接,数据仍然不变。

③ 事务关闭

选择性的将日志文件中操作的结果保存到数据表(同步)或者说直接清空事务日志(原来操作全部清空)

a) 提交事务:同步数据表(操作成功)–commit;
b) 回滚事务:直接清空日志表(操作失败)–rollback;

最终提交事务后,查看各自账户余额:

COMMIT;
select * from my_account;

这里写图片描述

【3】事务原理

事务开启之后,所有的操作都会临时保存到事务日志(可重执行日志)里面。事务日志只有在得到commit命令才会同步到数据表,其他任何情况都会清空(rollback,断电,断开连接等等)。

这里写图片描述

【4】事务回滚点

回滚点

在某个成功的操作完成之后,后续的操作有可能成功有可能失败。但是不管成功或者失败,前面的操作都已经成功。故可以在当前成功的位置,设置一个点---可以供后续失败操作返回到该位置,而不是返回所有操作,这个点称之为回滚点

设置回滚点语法

savepoint 回滚点名字;

回到回滚点语法

rollback to 回滚点名字;

示例如下

--开启事务
START TRANSACTION;

update p_user set age = 10 where id = 1;

--设置回滚点
SAVEPOINT point_name;

-- 假设错误操作
update p_user set age = 11 where id = 1;

--回滚到回滚点
ROLLBACK to point_name;

--关闭事务
COMMIT;

SELECT * from p_user where id = 1;

【5】自动事务(隐式事务)

在MySQL中,默认的是自动事务处理,用户操作完直接同步到数据表。自动事务是系统通过autocommit变量进行控制。

这里写图片描述

如果手动开启了事务,那么将使用手动事务(不再使用默认的自动事务)。默认自动事务为开启状态。

START  TRANSACTION;

update p_user set age= 20 where id = 1;

select * from p_user where id =1 ;

COMMIT;

如果关闭自动事务,那么需要手动提交(commit)或回滚(rollback)。

关闭自动事务语法:

set autocommit = 0/off;

开启自动事务语法:

set autocommit = 1/on;

关闭自动事务需要手动提交;

update p_user set age  = 10 where id = 1;
commit;

如果同时在两个窗口更新同一条数据呢?一个开启手动事务,一个使用默认事务

这里写图片描述

这里写图片描述

那么不好意思,后面那个将会抛出错误:
这里写图片描述

这就是MySQL的锁机制。

【6】JDBC 事务处理

事务处理

保证所有事务都作为一个工作单元来执行,即使出现了故障,都不能改变这种执行方式。当在一个事务中执行多个操作时,要么所有的事务都被提交(commit),要么整个事务回滚(rollback)到最初状态。

当一个连接对象被创建时,默认情况下是自动提交事务。:每次执行一个 SQL 语句时,如果执行成功,就会向数据库自动提交,而不能回滚。

为了让多个 SQL 语句作为一个事务执行:

  • 调用 Connection 对象的 setAutoCommit(false); 以取消自动提交事务;
  • 在所有的 SQL 语句都成功执行后,调用 commit(); 方法提交事务;
  • 在出现异常时,调用 rollback(); 方法回滚事务;
  • 若此时 Connection 没有被关闭, 则需要恢复其自动提交状态。
已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 程序猿惹谁了 设计师:上身试试 返回首页