MySQl中隔离级别和悲观锁乐观锁
1.MySql的事物支持
MySQL的事务支持不是绑定在MySQL服务器本身,而是与存储引擎相关:
- MyISAM:不支持事务,用于只读程序提高性能
- InnoDB:支持ACID事务、行级锁、并发
- Berkeley DB:支持事务
2.隔离级别
隔离级别决定了一个session中的事务可能对另一个session的影响、并发session对数据库的操作、一个session中所见数据的一致性
ANSI标准定义了4个隔离级别,MySQL的InnoDB都支持:
Java代码
- READ UNCOMMITTED:最低级别的隔离,通常又称为dirty read,它允许一个事务读取还没commit的数据,这样可能会提高性能,但是dirty read可能不是我们想要的
- READ COMMITTED:在一个事务中只允许已经commit的记录可见,如果session中select还在查询中,另一session此时insert一条记录,则新添加的数据不可见
- REPEATABLE READ:在一个事务开始后,其他session对数据库的修改在本事务中不可见,直到本事务commit或rollback。在一个事务中重复select的结果一样,除非本事务中update数据库。
- SERIALIZABLE:最高级别的隔离,只允许事务串行执行。为了达到此目的,数据库会锁住每行已经读取的记录,其他session不能修改数据直到前一事务结束,事务commit或取消时才释放锁。
可以使用如下语句设置MySQL的session隔离级别:
SET TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE}
MySQL默认的隔离级别是REPEATABLE READ,在设置隔离级别为READ UNCOMMITTED或SERIALIZABLE时要小心,READ UNCOMMITTED会导致数据完整性的严重问题,而SERIALIZABLE会导致性能问题并增加死锁的机率.
3.乐观锁和悲观锁的策略
乐观所和悲观锁策略:
悲观锁:在读取数据时锁住那几行,其他对这几行的更新需要等到悲观锁结束时才能继续 .
乐观所:读取数据时不锁,更新时检查是否数据已经被更新过,如果是则取消当前更新 .
一般在悲观锁的等待时间过长而不能接受时我们才会选择乐观锁.
悲观锁的例子:
CREATE PROCEDURE tfer_funds
(from_account INT, to_account INT,tfer_amount NUMERIC(10,2),
OUT status INT, OUT message VARCHAR(30))
BEGIN
DECLARE from_account_balance NUMERIC(10,2); START TRANSACTION; SELECT balance
INTO from_account_balance
FROM account_balance
WHERE account_id=from_account
FOR UPDATE; IF from_account_balance>=tfer_amount THEN UPDATE account_balance
SET balance=balance-tfer_amount
WHERE account_id=from_account; UPDATE account_balance
SET balance=balance+tfer_amount
WHERE account_id=to_account;
COMMIT; SET status=0;
SET message='OK';
ELSE
ROLLBACK;
SET status=-1;
SET message='Insufficient funds';
END IF;
END;
乐观锁的例子:
CREATE PROCEDURE tfer_funds
(from_account INT, to_account INT, tfer_amount NUMERIC(10,2),
OUT status INT, OUT message VARCHAR(30) ) BEGIN DECLARE from_account_balance NUMERIC(8,2);
DECLARE from_account_balance2 NUMERIC(8,2);
DECLARE from_account_timestamp1 TIMESTAMP;
DECLARE from_account_timestamp2 TIMESTAMP; SELECT account_timestamp,balance
INTO from_account_timestamp1,from_account_balance
FROM account_balance
WHERE account_id=from_account; IF (from_account_balance>=tfer_amount) THEN -- Here we perform some long running validation that
-- might take a few minutes */
CALL long_running_validation(from_account); START TRANSACTION; -- Make sure the account row has not been updated since
-- our initial check
SELECT account_timestamp, balance
INTO from_account_timestamp2,from_account_balance2
FROM account_balance
WHERE account_id=from_account
FOR UPDATE; IF (from_account_timestamp1 <> from_account_timestamp2 OR
from_account_balance <> from_account_balance2) THEN
ROLLBACK;
SET status=-1;
SET message=CONCAT("Transaction cancelled due to concurrent update",
" of account" ,from_account);
ELSE
UPDATE account_balance
SET balance=balance-tfer_amount
WHERE account_id=from_account; UPDATE account_balance
SET balance=balance+tfer_amount
WHERE account_id=to_account; COMMIT; SET status=0;
SET message="OK";
END IF; ELSE
ROLLBACK;
SET status=-1;
SET message="Insufficient funds";
END IF;
END$$
一个讲解比较清楚的博客推荐:http://blog.csdn.net/csh624366188/article/details/7654996
MySQl中隔离级别和悲观锁乐观锁的更多相关文章
- 从事务隔离级别谈到Hibernate乐观锁,悲观锁
数据库的事务,是指作为单个逻辑工作单元执行的一系列操作. 事务处理可以确保除非事务性单元内的所有操作都成功完成,否则不会永久更新面向数据的资源.通过将一组相关操作组合为一个要么全部成功要么全部失败的单 ...
- Mysql中的读锁,写锁,乐观锁及事务隔离级别和并发问题
mysql读锁,写锁,乐观锁 读锁,也叫共享锁(shared lock) SELECT * FROM table_name WHERE ... LOCK IN SHARE MODE 写锁,也叫排他 ...
- MySQL 中隔离级别 RC 与 RR 的区别
1. 数据库事务ACID特性 数据库事务的4个特性: 原子性(Atomic): 事务中的多个操作,不可分割,要么都成功,要么都失败: All or Nothing. 一致性(Consistency): ...
- Mysql事务隔离级别和锁机制
一.Spring支持四种事务隔离级别: 1.ISOLATION_READ_UNCOMMITTED(读未提交):这是事务最低的隔离级别,它充许令外一个事务可以看到这个事务未提交的数据. 2.ISOLAT ...
- mysql事务之一:MySQL数据库事务隔离级别(Transaction Isolation Level)及锁的实现原理
一.数据库隔离级别 数据库隔离级别有四种,应用<高性能mysql>一书中的说明: 然后说说修改事务隔离级别的方法: 1.全局修改,修改mysql.ini配置文件,在最后加上 1 #可选参数 ...
- MySQL 不同隔离级别,都使用了什么锁?
大家好,我是树哥. 在上篇文章,我们聊了「MySQL 啥时候会用表锁,啥时候用行锁」这个问题.在文章中,我们还留了一个问题,即:如果查询或更新时的数据特别多,是否从行锁会升级为表锁?此外,还有朋友留言 ...
- Java并发 行级锁/字段锁/表级锁 乐观锁/悲观锁 共享锁/排他锁 死锁
原文地址:https://my.oschina.net/oosc/blog/1620279 前言 锁是防止在两个事务操作同一个数据源(表或行)时交互破坏数据的一种机制. 数据库采用封锁技术保证并发操作 ...
- SQL Server 锁机制 悲观锁 乐观锁 实测解析
先引入一些概念,直接Copy其他Blogs中的,我就不单独写了. 一.为什么会有锁 多个用户同时对数据库的并发操作时会带来以下数据不一致的问题: 1.丢失更新 A,B两个用户读同一数据并进行修改,其中 ...
- mysql事务隔离级别和MVCC
一.三种问题: 脏读(Drity Read):事务A更新记录但未提交,事务B查询出A未提交记录. 不可重复读(Non-repeatable read):在一个事务的两次查询之中数据不一致,这可能是两次 ...
随机推荐
- 系统管理命令之tty
在Linux操作系统中,所有外围设备都有其名称与代号,这些名称代号以特殊文件的类型存放于/dev目录下.你可以执行tty指令查询目前使用的终端机的文件名称. 1.命令帮助: # tty -- help ...
- Bootstrap fileinput v3.0(ssm版)
说明在上一个版本即Bootstrap fileinput v2.0(ssm版)的基础上,增加了多处都需要上传的需求 核心代码ArticleController.java package com.isd ...
- 2017-2018 ACM-ICPC German Collegiate Programming Contest (GCPC 2017) Solution
A. Drawing Borders Unsolved. B. Buildings Unsolved. C. Joyride Upsolved. 题意: 在游乐园中,有n个游玩设施,有些设施之间有道路 ...
- hdu5880 Family View
地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=5880 题目: Family View Time Limit: 3000/1000 MS (Ja ...
- android,结合Timer和TimerTask实现定时任务
当我们需要每隔一段时间执行一个任务的时候,就需要使用TimerTask了,下面是入门的例子, 值得注意的是Timer.TimerTask,cancel之后就需要重新声明一个对象,否则会报错的哦~ pa ...
- tomcat jdbc pool
文中内容主要转自:http://www.open-open.com/lib/view/open1327478028639.html http://www.open-open.com/lib/view/ ...
- 0510进程 multiprocess模块
process模块是一个创建进程的模块,借助这个模块,就可以完成进程的创建. 创建模块 import os import time from multiprocessing import Proces ...
- 20145326 《Java程序设计》第7周学习总结
20145326 <Java程序设计>第7周学习总结 教材学习内容总结 第十二章 一.认识Lambda语法 1.Lambda语法概览 Arrays的sort()方法可以用来排序,只不过你要 ...
- Codeforces Round #394 (Div. 2) B. Dasha and friends(暴力)
http://codeforces.com/contest/761/problem/B 题意: 有一个长度为l的环形跑道,跑道上有n个障碍,现在有2个人,给出他们每过多少米碰到障碍,判断他们跑的是不是 ...
- 判断一个数是否是4的n次方
def is_Power_of_four(n): while n and not (n & 0b11): n >>= ) print(is_Power_of_four()) pri ...