作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO
联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬
学习必须往深处挖,挖的越深,基础越扎实!
阶段1、深入多线程
阶段2、深入多线程设计模式
阶段3、深入juc源码解析
码哥源码部分
码哥讲源码-原理源码篇【2024年最新大厂关于线程池使用的场景题】
码哥讲源码-原理源码篇【揭秘join方法的唤醒本质上决定于jvm的底层析构函数】
码哥源码-原理源码篇【Doug Lea为什么要将成员变量赋值给局部变量后再操作?】
码哥讲源码【谁再说Spring不支持多线程事务,你给我抽他!】
打脸系列【020-3小时讲解MESI协议和volatile之间的关系,那些将x86下的验证结果当作最终结果的水货们请闭嘴】
JDK动态代理
前面讲了事务注解的属性获取,如果发现有实例的方法有事务后面就会进行动态代理,其实和前面AOP
流程一样的。
实战
首先事务需要数据库支持,我们就用mysql
,然后需要数据源,我们用默认的DriverManagerDataSource
,然后我们还用JdbcTemplate
,然后还需要一个DataSourceTransactionManager
,否则用不了,会报异常。
TransactionConfig配置类
@Configuration
@PropertySource("classpath:db.properties")
@EnableTransactionManagement
public class TransactionConfig {
@Value("${jdbc.driver}")
private String driverClassname;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
@Bean
public DataSource dataSource() {
DriverManagerDataSource data = new DriverManagerDataSource();
data.setDriverClassName(driverClassname);
data.setUrl(url);
data.setUsername(username);
data.setPassword(password);
return data;
}
@Bean
public JdbcTemplate jdbcTemplate(DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
@Bean
public UserDao userDao() {
return new UserDaoImpl();
}
@Bean
public AccountDao accountDao() {
return new AccountDaoImpl();
}
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
}
db.properties数据库配置信息
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/db_mybatis?serverTimezone=UTC
jdbc.username=root
jdbc.password=123456
AccountDao
public interface AccountDao {
void insertTest1();
}
AccountDaoImpl
public class AccountDaoImpl implements AccountDao {
@Autowired
JdbcTemplate jdbcTemplate;
@Transactional(propagation = Propagation.REQUIRED)
@Override
public void insertTest1() {
Account account=new Account();
account.setMoney(100);
jdbcTemplate.update("insert into account (money) value(?)", new Object[]{account.getMoney()});
System.out.println(1 / 0);
}
}
UserDao
public interface UserDao {
void test();
}
UserDaoImpl
public class UserDaoImpl implements UserDao {
@Autowired
JdbcTemplate jdbcTemplate;
@Autowired
AccountDao accountDao;
@Transactional(propagation = Propagation.REQUIRED)
@Override
public void test() {
User user = new User();
user.setUsername("n1");
user.setPassword("p1");
jdbcTemplate.update("insert into user (username,password) value(?,?)", new Object[]{user.getUsername(), user.getPassword()});
accountDao.insertTest1();
}
}
测试方法
主要是用UserDao
的test
测试,里面调动另外一个AccountDao
的insertTest1
,这样起码有两个事物注解,基本可以演示7
个传播机制。
@Test
public void DBTest() {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
applicationContext.register(TransactionConfig.class);
applicationContext.refresh();
UserDao userDao = applicationContext.getBean(UserDao.class);
userDao.test();
}
后面基本就是围绕这个例子来改的,来揭露7
大传播机制的底层原理。