作者回复: 我读了半天,终于理解到你说的是FooService……我invokeInsertThenRollback虽然没有开启事务,但是我方法内部调用的代理类的insertThenRollback是有事务的。另外,你并不知道我一开始调用的fooService. invokeInsertThenRollback是不是走的代理类,通常我们都有各种增强,只是增强的内容不一样,我们经常接触到的都是代理类,只是你感觉不到而已。
作者回复: 额,建议还是先看下课程前的基础知识说明,先了解一些基础的必备知识。Spring的书,要不看看Spring in Action吧,Maven的基本使用,网上找些文章看看一般就行了。
作者回复: 你这个就属于分布式事务啦,你在本地事务里调用了远程服务,那个服务如果成功了,你本地事务回滚,远程的事务都已经提交了。你要自己考虑怎么去回滚它。可以了解下BASE和TCC这些概念。
作者回复: for update是在事务里锁住记录,你不加事务,那就单条select锁了立马就放了,所以不会hold其他请求。加了事务,不加for update,其他请求也不会hold住。
作者回复: 这些都是Lombok提供的,你是不是没有在IDE里装Lombok插件?我在答疑时强调了一定要安装Lombok插件。
作者回复: 点开@Builder注解,你会看到还有@Default注解好用
作者回复: 我按自己的理解说一下,仅供参考。假设你的多租户是B端的商户,一般商户也会分小商户、中型商户和大商户,小商户大家可以共用一套表,中型的自己独占一套,大商户自己还需要分库分表。可以通过中间件配合路由表来实现。系统里只要保证每次操作数据库都带上商户号,剩下的交给中间件就好了。
作者回复: 显然你真的是没有搞明白这些东西的含义……JPA和JDBC都是规范,JPA可以看做ORM的一套规范,Hibernate是JPA的实现;JDBC提供了Java数据库操作的底层规范,各种连接啊、查询啊什么的操作都是JDBC来定义的,不同数据库都提供了遵循JDBC的驱动;Druid和HikariCP都是数据源,或者简单点说是数据库连接池;ShardingShpere是用来做分库分表。平时这些东西是要根据实际情况结合在一起来使用。
作者回复: 我看了那个文章,他自己用CGLIB增强了一下类,这个增强逻辑和Spring的还是有区别的。我准备了个简单的DEMO(https://github.com/digitalsonic/geektime-everyday/tree/master/aop/transaction-demo),你可以下载下来DEBUG一下,尤其是DataService.invokeMethod(),你可以看看执行到这里时的this是哪个对象。
作者回复: 按照我的理解,有没有注解,调用被代理类增强的方法都是需要特殊处理的。不太清楚你的模拟场景,可以把代码贴到Github或者码云里,我们可以一起看看。
作者回复: 不用安装,是内嵌的。如果你一定要在程序以外运行一个,它有命令行的,你从H2官网下载一个包,然后解压,到bin目录里执行命令可以启动一个独立的H2
作者回复: 官方文档后面有个附录可以查,另外,我们在课程里也带大家看了很多自动配置类,每个属性类也会对应到配置项上。也可以通过配置属性类来反推出配置项。
作者回复: 你要看是哪个AOP先执行的,一般情况下你的AOP是在事务的AOP里面的,除非你自己设置的AOP的拦截顺序。所以你抛异常了,外面的事务的AOP拦截器就捕获到异常,接着回滚了。
作者回复: 这个看你们的业务了,不同的业务系统中“慢”的定义是不一样的,可以结合具体情况再咨询下你们公司的DBA。比如你系统里大部分SQL都是1ms内执行完的,那同一个系统里突然来条100ms的SQL,它就是慢SQL了。
作者回复: 多线程之间最好事务隔离开,线程里用自己的事务。