-- 准备测试数据
drop database if exists `java_basic`;
create database if not exists `java_basic` charset utf8mb4;
use `java_basic`;
create table if not exists `account`
(
`id` int auto_increment primary key not null comment '编号',
`name` varchar(32) not null comment '姓名',
`balance` double not null comment '余额'
) comment '账户表';
truncate table `account`;
insert into `account` (`name`, `balance`)
values ('zhang3', 2000),
('li4', 2000);
select *
from `account`;
drop procedure if exists transfer;
create procedure transfer(in from_acc int, in to_acc int, in amount double)
begin
if
(select `id`
from `account`
where `id` = from_acc) is null then
signal sqlstate 'JB001'
set message_text = '转账账户不存在';
elseif
(select `id`
from `account`
where `id` = to_acc) is null then
signal sqlstate 'JB001'
set message_text = '收款账户不存在';
elseif
(select `balance`
from `account`
where `id` = from_acc) < amount then
signal sqlstate 'JB002'
set message_text = '余额不足';
else
start transaction;
update `account`
set `balance` = `balance` - amount
where `id` = from_acc;
if rand() * 5 < 4 then
rollback;
signal sqlstate 'JB999'
set message_text = '模拟异常';
end if;
update `account`
set `balance` = `balance` + amount
where `id` = to_acc;
commit;
end if;
end;
call transfer(1, 2, 100);
select *
from `account`;
select @@autocommit;
set @@autocommit = 1;
start transaction;
commit;
rollback;
select @@transaction_isolation;
set session transaction isolation level repeatable read;
- 原子性(Atomicity) :事务是不可分割的最小单元, 要么同时成功, 要么同时失败
- 一致性(Consistency): 事务完成时, 必须所有的数据都保持一致状态
- 隔离性(Isolation) : 数据库系统提供的隔离机制, 保证事务在不受外部并发操作影响的独立环境下运行
- 持久性(Durability): 事务一旦提交或回滚, 他对数据库中的数据的改变就是永久的
- 脏读: 一个事务读取到另一个事务还没有提交的数据
- 不可重复读: 一个事务先后读取同一条数据, 但两次读取的数据不同
- 幻读: 一个事务按条件查询数据时, 没有对应的数据行, 但是在插入数据时, 但这行数据又出现了
隔离级别 |
脏读 |
不可重复读 |
幻读 |
Read uncommmotted |
存在 |
存在 |
存在 |
Read committed |
|
存在 |
存在 |
Repeatable Read(默认) |
|
|
存在 |
Serializable |
|
|
|