事务的底层原理——锁
事务的概念
我们知道,在JavaEE的开发过程中,service方法用于处理主要的业务逻辑,而业务逻辑的处理往往伴随着对数据库的多个操作。以我们生活中常见的转账为例,service方法要实现将A账户转账到B账户的功能,则该方法内必定要有两个操作:先将A账户的金额减去要转账的数目,然后将B账户加上相应的金额数目。这两个操作必定要全部成功,方才表示本次转账成功;若有任何一方失败,则另一方必须回滚(即全部失败)。事务指的就是这样一组操作:这组操作是不可分割的,要么全部成功,要么全部失败
事务的特性
事务具有ACID四个特性:
原子性(Atomicity):事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生
一致性(Consistency):事务在完成后数据的完整性必须保持一致
隔离性(Isolation):多个用户并发访问数据库时,一个用户的事务不能被其他用户的事务所干扰,多个并发事务之间的数据要相互隔离
持久性(Durability):一个事务一旦被提交,它对数据库中数据的改变应该是永久性的,即使数据库发生故障也不应该对其有任何影响
脏读 :一个事务读到了另一个事务的未提交的数据
不可重复读 :一个事务读到了另一个事务已经提交的 update 的数据导致多次查询结果不一致
幻读 :一个事务读到了另一个事务已经提交的 insert 的数据导致多次查询结果不一致
ISOLATION_DEFAULT:使用数据库默认的隔离级别
ISOLATION_READ_UNCOMMITTED:最低的隔离级别,允许读取已改变而没有提交的数据,可能会导致脏读、幻读或不可重复读
ISOLATION_READ_COMMITTED:允许读取事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生
ISOLATION_REPEATABLE_READ:对同一字段的多次读取结果都是一致的,除非数据事务本身改变,可以阻止脏读和不可重复读,但幻读仍有可能发生
ISOLATION_SERIALIZABLE:最高的隔离级别,完全服从ACID的隔离级别,确保不发生脏读、不可重复读以及幻读,也是最慢的事务隔离级别,因为它通常是通过完全锁定事务相关的数据库表来实现的
级别结论:数据库隔离级别越高,执行代价越高,并发执行能力越差,因此在实际项目开发使用时要综合考虑,为了考虑并发性能一般使用提交读隔离级别,它能避免丢失更新和脏读,尽管不可重复读和幻读不能避免,但可以在可能出现的场合使用悲观锁或乐观锁来解决这些问题。
为了防止这些上述情况的发生,所以引入了锁。
在mysql中,默认有隐式锁,在执行insert update delete,Mysql默认自动处理事务。(现在数据量少,为行锁)
BEGIN开启手动提交事务。
脏读现象:

保护机制:当行锁数据量超过一定阀值,行锁转换为表锁。
1.LOCK TABLE book READ -> 其他会话只能读也不能写
2.LOCK TABLE book WRITE -> 其他会话既不能读也不能写
3.UNLOCK TABLES
注意:InnDB聚集索引(行锁 表锁) 非聚集索引(表锁)
所谓聚集,指实际数据行和相关的键值保存在一块,这也决定了一个表只能有一个聚集索引,即MySQL不会一次把数据行保存在二个地方。InnoDB通常根据主键值(primary key)进行聚集,但是当一个表没有PK怎么办?InnoDB选取聚集索引参照列的顺序是:
如果声明了主键(primary key),则这个列会被做为聚集索引
如果没有声明主键,则会用一个唯一且不为空的索引列做为主键,成为此表的聚集索引
上面二个条件都不满足,InnoDB会自己产生一个虚拟的聚集索引。
1.

在Oracle中
DDL -> 自动提交事务 CREATE ALTER DROP TRUNCATE
DML -> 手动提交事务 INSERT UPDATE DELETE
1)影响范围
行锁
UPDATE dept_bf SET dname = 'XX' where deptno = 20;
SELECT * FROM dept_bf where deptno =20 for update nowait;
表锁
lock table dept_bf in share mode;
参考博客:https://www.cnblogs.com/liantdev/p/10149443.html

浙公网安备 33010602011771号