1、mysql在del、update 操作的是,都应该使用事务,mysql默认事务级别为可重复读
2、在Spring框架下只需要关注,获取锁;事务的开始和结束有框架完成
SELECT * FROM products WHERE id='3' FOR UPDATE;
备注:mysql默认引擎为InnoDB,InnoDB默认预设的是Row-Level-Lock(行级锁),因此必须要明确的制定主键,mysql才会执行Row Lock(只锁住被选取的数据),否则mysql会执行Table Lock(表级锁)。
以下的语句mysql都执行的是Table Lock(表级锁)
//不可能找到id=-1的数据
SELECT * FROM products WHERE id='-1' FOR UPDATE;
//没有明确的指定主键
SELECT * FROM products WHERE name='张三' FOR UPDATE;
//没有明确的指定主键
SELECT * FROM products WHERE id<>'3' FOR UPDATE;
//没有明确的指定主键
SELECT * FROM products WHERE id LIKE '3' FOR UPDATE;
3、在非框架环境,完整的事务锁代码如下
SET AUTOCOMMIT=0; BEGIN WORK; SELECT quantity FROM products WHERE id=3 FOR UPDATE;
UPDATE products SET quantity = '1' WHERE id=3 ; COMMIT WORK;
语句解析:
1、SET AUTOCOMMIT=0; 停止mysql的自动提交,转而需要显式的commit提交
2、BEGIN WORK; 事务开始
3、SELECT quantity FROM products WHERE id=3 FOR UPDATE;
products中的id=3 的数据被锁住,此时其他事务中如果也需 要对products 中的id=3的数据,即其他的事务中也有通过
SELECT quantity FROM products WHERE id=3 FOR UPDATE,语句来获取products中id=3的数据的锁,就需要等到其他事务结束也就是commit提交后,才能回执行该语句。普通的select查询是不收影响的。
4、UPDATE products SET quantity = '1' WHERE id=3 ;做update操作
5、COMMIT WORK;提交事务。
tips:
事务的四大特性:原子性、一致性、隔离性、持久性
其中隔离性本质是通过锁的机制来实现的,也可能会利用版本号控制(SQL Server 2005 及以上、orcal)来实现。
事务的隔离级别是并发的整体解决方案
锁是数据库并发控制的内部机制