事务:
事务就是 Socket 连接
JDBC 的链接
1. 如果是 SELECT 拿到直接返回就好了
2. 把找出来地记录放到内存中
3. 异常,检查有没有这条数据,再检查 SQL
语句是不是有语法错误,等等,然后在内存中修改这条数据。修改完以后,会去检查,比如说外键关联了之类的问题。发现不能改了又会报错。
只有当更新以后完全没有问题了,才会把这条数据给替换掉。
有些数据库采用的是增量,有些数据库采用的是直接替换。
一般数据库都是采用的 增量的模式,会用用内存中的数据把原来的数据给盖掉。
4. 数据操作没有任何异常的话,更新原始表,写日志
数据库一定会写日志。
5. 返回状态码
update 过程图解:
锁表-行锁、表锁
这条更新的目标记录,如果需要对这个表进行扫描的话,这里会把整个表都锁住,然后把整张表都同步到内存中,那么这个表就不允许任何的增删改操作。如果,这条记录查出来,方法大内存里边的话,这时候就是行锁。这条记录如果转移到缓存区里的话,这条记录绝对绝不允许别人去修改的。只有当我把缓冲区的数据消掉以后,更新到数据库里边,这条记录才会呗解锁,其他更新才能进行。
日志:
Mysql : binlog
记录事务的开始到结束,还有中间的报错,以及整个链接成功与否还有返回结果,状态码,查出来是什么,更新的是什么。都会记录下来。如果报错了,就不会再记录了,它会再找回去,逆向的一步一步执行回去。这就是要给回滚的过程,就会根据这个记录一条一条回滚。日志中,一定要包括,操作的记录,日志,还有事件。
这个 log 非常非常重要。回滚也会记录日志。
如果,id 自增的话,添加 id = 5 ,失败,回滚,然后,id 下一次就会是 6。
insert
首先检查原始表中有没有相关联的记录,先把相关联的记录写到内存中来,只有我们的缓冲区没有任何的异常,它才会把这条记录写进去。(通常会根据 id 来识别,数据类型,外键,索引)
Delete
我们先把相关联的数据放到内存中,比较之后,没有异常,同步到数据库表中去。
增删改都有锁 , for update
-- 会把整个表都锁住了
DELECT FROM member;
-- 会把整个表都锁住了
DELECT FROM member;
2
SQL (Struction Query Language)本身就是一种协议。
事务只是一个概念,多条语句一起执行,只有一个连接,如果一条一条执行,那就有多个连接。
一个连接一个 Socket 。
如果你 setAutoCommit(false);
commit();
手动提交就行了。
AOP:
AOP : 解耦。(专人干专事) Aspect(切面)
面向接口编程是一种接口,
MVC 编程是一种解耦。
三层架构 Dao、Service、Action 是一种解耦
微服务化也是一种解耦
以 Class 为单位的纵向的街头(传统)
横切,横向解耦(面向范畴可能多个类之间)
如何切:
规则
面向切面编程就是 面向规则编程 。
Spring ---------- JDK
织入 ---------- 字节码重组 ProxyClassLoad
增强 ---------- 动态代理 InvocationHandler
切面 规则:事务管理的切面由Spring 提供,业务相关的切面由自己实现
切点 能够满足虚拟切面规则的所有入口
通知 满足条件的回调
自古文人都是贼,这些底层都是一样的。叫 借鉴
Spring MVC、Spring WebFlux、Spring Boot
事务AOP图解:
@Before("aspect()&&args(id)")
public void beforeArgId(JoinPoint joinPoint, long id){
log.info("beforeArgId " + joinPoint + "\tID:" + id);
}
@Before("aspect()&&args(id)")
public void beforeArgId(JoinPoint joinPoint, long id){
log.info("beforeArgId " + joinPoint + "\tID:" + id);
}
2
3
4
annotation 更加强大