mysql中的事务、锁与线程安全
来源:互联网 发布:sdspage电泳结果数据 编辑:程序博客网 时间:2024/05/22 14:14
事务具有ACID特性,锁只是实现这些特性的必须机制。
mysql> SELECT @@tx_isolation;+----------------+| @@tx_isolation |+----------------+| SERIALIZABLE |+----------------+1 row in set (0.00 sec)mysql> BEGIN ;Query OK, 0 rows affected (0.00 sec)mysql> SELECT @temp:=tag FROM orders WHERE id = 1;+------------+| @temp:=tag |+------------+| 0 |+------------+1 row in set (0.00 sec)mysql> UPDATE orders SET tag=@temp+1 WHERE id = 1;Query OK, 1 row affected (0.04 sec)Rows matched: 1 Changed: 1 Warnings: 0mysql> COMMIT;
以上代码使用了最高的事务隔离级别,是否意味着线程安全?
答案为否。
做如下验证,开启两个SESSION:S1与S2:
- S1开启事务并读入@temp
- S2开启事务并读入@temp
- S1修改tag+1并提交事务
- S2修改tag+1并提交事务
最后tag的结果为1,WHY?
原因在于@temp
做如下改动:
mysql> UPDATE orders SET tag= tag+1 WHERE id = 1;Query OK, 1 row affected (0.04 sec)Rows matched: 1 Changed: 1 Warnings: 0
流程不变,结果tag为2,发生了什么?
Mysql在Update时,对记录加了排他锁,直到事务提交以后将其释放。
所以,在事务中,执行单个UPDATE|DELTET|INSERT语句是线程安全的。但是,执行多个语句却未必安全。通常,作为前置条件,@temp的存在是必要的。假设,当@temp>0时,不希望再增加tag的值,也就是,最终希望结果为1。然而,只依赖事务隔离却无法保证结果的准确性。如果对并发情况下的结果要求很严格,那么如何保证事务的线程安全?
加悲观锁:
mysql> SELECT @temp=tag FROM orders WHERE id = 1 FOR UPDATE;+-----------+| @temp=tag |+-----------+| 0 |+-----------+1 row in set (0.00 sec)
这样,S1便独占了排他锁,直到事务提交后释放。
需要注意的是,事务的作用域要尽量小,操作的记录要尽量少,以及记录中避免出现热点数据。
总之,Mysql事务的绝对线程安全,需要用悲观锁保证。
阅读全文
0 0
- mysql中的事务、锁与线程安全
- MySQL中的事务与锁
- MySQL中的事务与锁
- 类型安全 与 线程安全 、异常安全、事务安全
- java中的线程安全与锁优化
- JAVA中的线程安全与非线程安全
- JAVA中的线程安全与非线程安全
- JAVA中的线程安全与非线程安全
- JAVA中的线程安全与非线程安全
- JAVA中的线程安全与非线程安全
- JAVA中的线程安全与非线程安全
- mysql事务与锁
- MySql 事务与锁
- MySQL锁与事务
- Mysql事务中的锁,行锁与表锁
- java5中的 Map 与线程安全
- java5中的 Map 与线程安全
- java5中的 Map 与线程安全
- 匿名函数(Lambda表达式)与箭头函数
- http respond header
- VRTK 实现菜单出现在视野前方(HTC设备)
- mybatis详解-(8)配置自增主键
- python怎么实现发现所需目录不存在时新建目录
- mysql中的事务、锁与线程安全
- 7、死锁
- 购买饲料
- Python爬虫-基于深度优先策略的百度百科爬虫
- [机器学习]PCA (主成分分析)详解
- 驱动开发概述
- 【web前端自动化工作环境配置】11. 生产环境的适配
- poi操作ppt生成文本框
- 浅拷贝和深拷贝(谈谈java中的clone)