-- 查看当前会话的隔离级别
select @@tx_isolation;
-- 设置当前会话隔离级别
set session transaction isolation level serializable;
-- 查看系统当前隔离级别
select @@global.tx_isolation;
-- 设置系统当前隔离级别
set global transaction isolation level repeatable read;
-- 取消自动提交
set autocommit=0;
-- 事务的并发问题
-- 脏读 :读未提交
-- 不可重复读 :读已提交
-- 幻读
-- 事务的隔离级别
-- 读未提交(read-uncommitted)
-- 不可重复读(read-committed)
-- 可重复读(repeatable-read)
-- 串行化(serializable)
-- mysql 锁——serializable
set autocommit=0;
set session transaction isolation level serializable;
START TRANSACTION;
SELECT * FROM gongzi;
INSERT INTO `yanglei_test`.`gongzi` ( `name`, `money`) VALUES ( 'E', '100');
INSERT INTO `yanglei_test`.`user_info` (`name`, `age`) VALUES ( '1', '1');
COMMIT;
-- 引发死锁
事务的并发问题
1、脏读:事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据
2、不可重复读:事务 A 多次读取同一数据,事务 B 在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果 不一致。
3、幻读:系统管理员A将数据库中所有学生的成绩从具体分数改为ABCDE等级,但是系统管理员B就在这个时候插入了一条具体分数的记录,当系统管理员A改结束后发现还有一条记录没有改过来,就好像发生了幻觉一样,这就叫幻读。
小结:不可重复读的和幻读很容易混淆,不可重复读侧重于修改,幻读侧重于新增或删除。解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表
MySQL事务隔离级别
事务隔离级别 | 脏读 | 不可重复读 | 幻读 |
读未提交(read-uncommitted) | 是 | 是 | 是 |
不可重复读(read-committed) | 否 | 是 | 是 |
可重复读(repeatable-read) | 否 | 否 | |
串行化(serializable) | 否 | 否 | 否 |
//如果先申请共享锁,修改时再请求排他锁,那样容易产生死锁
@Override
@Transactional(rollbackFor = Exception.class,timeout = 16000,isolation = Isolation.SERIALIZABLE)
public void doLogSelective2(CompLog compLog) throws InterruptedException {
log.info("=============开始进来睡眠3s,然后获取独占写锁============1");
Thread.sleep(3 * 1000);
compLog.setJobId(3333L);
compLog.setId(35L);
compLogMapper.updateByPrimaryKey(compLog);
Thread.sleep(3 * 1000);
log.info("============接着查询=============2");
compLogMapper.selectAll();
log.info("=============更新============3");
compLog.setJobId(666L);
compLogMapper.updateByPrimaryKey(compLog);
Thread.sleep(5 * 1000);
log.info("=============1111============END");
}