事务提交时做的操作:

提交前:

        生成回滚记录;

        Redo日志缓冲区生成redo日志,等待写入日志包刷盘;

        修改的数据写入数据缓冲区,等待刷盘(以SQL为单位,不以事务为单位)。

提交后:

        事务形成的梗概写入日志文件并最终写入数据文件;

        释放事务上的所有锁,这个操作标志着事务的完成;

        返回提交成功消息。

事务的提交方式:

        自动提交:

set autocommit on;

        手动提交:等待commit语句提交或rollback语句回滚

        隐式提交:手动提交模式中,遇到DDL语句时自动提交前面事务,并以一个新事务执行DDL语句的情况

事务的回滚:

        自动回滚(连接断开;数据库恢复);

        程序或rollback命令回滚;

        回滚到savepoint(回滚保存点之后的语句=>清除之后的所有保存点=>释放保存点之后获得的所有锁;仍是活动事务);

        语句级回滚(ini中ROLL_ON_ERR=0,语句的执行错误会导致语句级回滚,但是解析错误不会导致语句级回滚)。

事务与锁:

锁模式:X(排他锁)、S(共享锁)、IX(意向排他锁)、IS(意向共享锁)

锁粒度:

        tid锁(行锁);

        对象锁:对统一的对象id进行封锁,合并数据字典锁(确保同一个对象的DDL川兴执行;确保修改字典结构的同时另一个事务添加数据)和表锁(防止多个事务批量更新一张表;防止向fsldr装载的表插入数据;防止对未提交修改的表alter或truncate)。

对象锁的逻辑分类:

        独占访问:加X锁

        独占修改:加S+IX锁

        共享修改:加IX锁

        共享访问:加IS锁

显示锁定表:

LOCK TABLE <tb_name> IN <lock_mode> MODE [NOWAIT];

其中tb_name为表名,lock_mode=INTENT SHARE/INTENT EXCLUSIVE/SHARE/EXCLUSIVE,即锁的四种模式;指定NOWAIT时,若不能立即上锁则返回报错信息,而不是等待加锁。

锁查看:

查询动态视图V$LOCK,获取锁的内存地址、事务id、类型、模式等。

阻塞和死锁:

        死锁的原因:形成了资源请求的等待环

        DM处理死锁的策略:随机牺牲其中一个事务,直到不形成死锁为止

阻塞的常见情况:

        Insert:多个事务向具有唯一约束(prime,unique)的表插入相同的数据,发生阻塞:一个事务提交时,其他事务收到报错;一个事务回滚时,被阻塞的事务可以继续执行

        Update、delete:修改的记录已经被另外的事务修改过,发生阻塞。

事务与多版本并发:

DM的隔离级别:

读已提交:

set transaction isolation level read commied;

实现方法:只能访问事务的提交的数据

问题:不可重复读;幻读

可串行化:

set set transaction isolation level serializable;

实现方式:事务的串行化执行

问题:修改数据肯引发“串行化事务被打断”错误;存在长时间运行的写事务,且操作的数据被短失误频繁更新时,可能导致对相同数据行的竞争,产生大量回滚

读未提交:

set set transaction isolation level read uncommied;

实现方式:可以访问事务未提交的数据

问题:脏读、不可重复读、幻读

使用场景:访问只读表和只读视图,取消并发判断开销,提升查询性能

只读事务:

set transaction read only;

特点:只能访问数据,不能修改;不会改变原有的隔离级别

达梦在线服务平台:达梦数据库 - 新一代大型通用关系型数据库 | 达梦在线服务平台

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐