声明式事物
V哥官网:http://www.vgxit.com
本文对应视频教程:http://www.vgxit.com/course/23
1,概述
声明式式事物是一种约定性的事物,在大部分情况下,当数据库使用事物的时候。一般我们都是发生了异常就需要事物回滚,如果没有繁盛异常,那么久提交事物。从这一点出发,Spring给了我们一个约定,就是没有异常提交事物,有异常回滚事务。通过这种思想,为我们提供了声明式事物。
2,具体实现:
我们这里要实现必须通过一个注解@Transactional。被这个注解修饰的方法就自动的会按照Spring给我们的约定管理起了事务。
1,我们首先在xml中开启申明式事务:
<tx:annotation-driven transaction-manager="transactionManager"/>
2,编写对应的业务逻辑代码:
package com.vgxit.learn.springtransaction.bk;
import lombok.Getter;
import lombok.Setter;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.annotation.Transactional;
@Getter
@Setter
@Transactional
public class User1Service {
private JdbcTemplate jdbcTemplate;
public void updateUser() {
jdbcTemplate.update("update user set name=? where id=?", "111111", 31);
throw new RuntimeException();
}
}
3,编写对应的测试代码:
private static void testShenmingTransaction() {
ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-cfg.xml");
User1Service user1Service = ctx.getBean(User1Service.class);
user1Service.updateUser();
}
4,我们的Transactional注解,可以配置在类上,也可以配置在方法上,配置在类上,所有的类的public方法都会起作用,如果作用在方法上,对应的方法起作用
3,纯注解的方式实现申明式事物
1,定义配置类:
package com.vgxit.learn.spring.ktdm.trananno.config;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import com.vgxit.learn.spring.ktdm.trananno.base.BaseMapper;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.TransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
import java.io.InputStream;
import java.util.Properties;
@Configuration
@ComponentScan("com.vgxit.learn.spring.ktdm.trananno")
@EnableTransactionManagement//启用申明式事物
public class TranannoConfig {
@Bean
public DataSource dataSource() throws Exception {
Properties properties = new Properties();
InputStream druidInputStream = TranannoConfig.class.getClassLoader().getResourceAsStream("datasource.properties");
properties.load(druidInputStream);
DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);
return dataSource;
}
@Bean("sqlSessionFactoryBean")
public SqlSessionFactoryBean sqlSessionFactoryBean(@Autowired DataSource dataSource) throws Exception {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
Resource resource = new ClassPathResource("mybatis-config.xml");
sqlSessionFactoryBean.setConfigLocation(resource);
return sqlSessionFactoryBean;
}
@Bean
public MapperScannerConfigurer mapperScannerConfigurer() {
MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
mapperScannerConfigurer.setBasePackage("com.vgxit.learn.spring.ktdm.trananno.mapper");
mapperScannerConfigurer.setSqlSessionFactoryBeanName("sqlSessionFactoryBean");
mapperScannerConfigurer.setMarkerInterface(BaseMapper.class);
return mapperScannerConfigurer;
}
@Bean
public TransactionManager transactionManager(@Autowired DataSource dataSource) throws Exception {
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
transactionManager.setDataSource(dataSource);
return transactionManager;
}
}
2,定义对应的UserService:
package com.vgxit.learn.spring.ktdm.trananno.service;
import com.vgxit.learn.spring.ktdm.trananno.mapper.UserMapper;
import com.vgxit.learn.spring.ktdm.trananno.po.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
@Component
public class UserService {
@Autowired
private UserMapper userMapper;
@Transactional
public void add(User user) {
userMapper.add(user);
// int x = 1 / 0;
}
}
3,具体的注入方法:
package com.vgxit.learn.spring.ktdm.trananno.test;
import com.vgxit.learn.spring.ktdm.trananno.config.TranannoConfig;
import com.vgxit.learn.spring.ktdm.trananno.po.User;
import com.vgxit.learn.spring.ktdm.trananno.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class TranannoTest001 {
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(TranannoConfig.class);
UserService userService = ctx.getBean(UserService.class);
User user = User.builder().name("沙悟净").age(550).gender((short) 1).nickName("卷帘大将").build();
userService.add(user);
}
}