1. spring事务
1.1 是什么?
单个逻辑单元执行一系列的事;
spring事务的本质就是对数据库事务的支持。
1.2 目的
为了保证数据的完整性和一致性;事务包含一系列的动作,一旦其中有一个动作出现错误,就全部进行回滚,将已完成的操作撤销。
1.3 spring事务特性
spring事务管理策略类继承自:org.springframework.transaction.PlatformTransactionManager
这个接口;
在TransactionDefinition接口中定义了一下特性:
事务隔离级别;
事务传播行为;
事务超时;
事务只读属性;
spring事务回滚规则;
1.4 声明式事务管理配置的两种方式(以mybatis为例)
1.4.1 xml配置文件的方式
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<context:component-scan base-package="com.service"/>
<context:property-placeholder location="classpath:db.properties"/>
<bean id="ds" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.user}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="ds"/>
<!--mapper对应实体包位置-->
<property name="typeAliasesPackage" value="com.entity"/>
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<!--mapper xml文件-->
<!--<property name="mapperLocations" value="classpath:com/mapper/*.xml"/>-->
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--mapper接口-->
<property name="basePackage" value="com.mapper"/>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>
<!--配置声明式事务-->
<bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="ds"/>
</bean>
<!--配置事务增强-->
<tx:advice id="txAdvice" transaction-manager="dataSourceTransactionManager">
<tx:attributes>
<!--以insert开头的方法-->
<tx:method name="insert*" propagation="REQUIRES_NEW" rollback-for="java.lang.ArithmeticException"/>
</tx:attributes>
</tx:advice>
<!--aop 配置-->
<aop:config proxy-target-class="true">
<aop:pointcut id="pc" expression="execution(* com.service.impl.*.*(..))"/>
<!--通过advisor将切面和切入点关联起来-->
<aop:advisor advice-ref="txAdvice" pointcut-ref="pc"/>
</aop:config>
</beans>
1.4.2 注解方式
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<context:component-scan base-package="com.service"/>
<context:property-placeholder location="classpath:db.properties"/>
<bean id="ds" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.user}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="ds"/>
<!--mapper对应实体包位置-->
<property name="typeAliasesPackage" value="com.entity"/>
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<!--mapper xml文件-->
<!--<property name="mapperLocations" value="classpath:com/mapper/*.xml"/>-->
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--mapper接口-->
<property name="basePackage" value="com.mapper"/>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>
<!--配置声明式事务-->
<bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="ds"/>
</bean>
<tx:annotation-driven transaction-manager="dataSourceTransactionManager"/>
</beans>
在事务管理的类或者方法上添加注解 @Transactional
@Service
public class RoleServiceImpl implements IRoleService {
@Resource
private RoleMapper roleMapper;
@Resource
private IDeptService deptService;
@Override
@Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
public int insertRole(Role role) {
Integer count = roleMapper.insertRole(role);
deptService.insertDept(new Dept("d5"));
return count;
}
}
在类上使用时,类中所有的public方法都将使用事务;若类中某个方法不想使用事务,则可以使用:@Transactional(propagation = Propagation.NOT_SUPPORTED)
1.5 事务的传播性
① @Transactional(propagation=Propagation.REQUIRED):默认级别;特点:上下文中存在事务,就加入该事务中执行,不存在事务就新建事务执行;
② @Transactional(propagation=PROPAGATION.SUPPORTS):支持;特点:上下文中有事务就加入事务中执行,没有事务就用非事务的方式;
③ @Transactional(propagation=PROPAGATION.MANDATORY):强制;特点:上下文必须存在事务,否则抛出异常;
④ @Transactional(propagation=PROPAGATION.REQUIRES_NEW):要求新的;特点:每次都要新建一个事务,同时将上下文中的事务挂起,当新建事务执行完成后,再恢复执行;
⑤ @Transactional(propagation=PROPAGATION.NOT_SUPPORTED) :不支持;特点:上下文中存在事务则挂起事务,执行当前逻辑,结束后恢复上下文事务;
⑥ @Transactional(propagation=PROPAGATION.NEVER):无事务;特点:要求上下文中不能存在事务,有事务则抛出runtime异常,强制停止执行;
⑦ @Transactional(propagation=PROPAGATION.NESTED):嵌套级别;特点:上下文中存在事务则嵌套事务执行,不存在事务则新建事务。
1.6 事务的隔离级别
用于多事务并发执行时;
① @Transactional(isolation = Isolation.SERIALIZABLE):事务串行执行;
② @Transactional(isolation = Isolation.REPEATABLE_READ):保证事务不会修改由另一个事务读取但是未提交(回滚)的数据;
③ @Transactional(isolation = Isolation.READ_COMMITTED):大多主流数据库的默认事务级别,保证了一个事务不会读到另一个并行事务已经修改但未提交的数据;
④ @Transactional(isolation = Isolation.READ_UNCOMMITTED):保证读取过程中不会读取到非法数据。
2. 定时任务
spring相关的包+
<!--定时任务需要的包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>5.3.10</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.2</version>
</dependency>
2.1 配置文件方式
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd">
<context:component-scan base-package="com.service,com.advise,com.util"/>
<task:scheduled-tasks>
<task:scheduled ref="myTask" method="job1" cron="* * * * * *"/>
</task:scheduled-tasks>
</beans>
@Component("myTask")
public class TaskJob {
public void job1(){
System.out.println("rr!"+ LocalDateTime.now());
}
public void job2(){
System.out.println("ww!"+LocalDateTime.now());
}
}
2.2 使用注解方式
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd">
<context:component-scan base-package="com.service,com.advise,com.util"/>
<context:annotation-config/>
<!--开启这个配置spring才能识别@Scheduled注解-->
<task:annotation-driven />
</beans>
public class TaskJob {
@Scheduled(cron = "3 1 * * * *")
public void job1(){
System.out.println("rr!"+ LocalDateTime.now());
}
@Scheduled(cron = "*/5 * * * * *")
public void job2(){
System.out.println("ww!"+LocalDateTime.now());
}
}
2.3 cron表达式
字段(按顺序,共6个) | 允许值 | 允许的特殊字符 |
秒 | 0-59 | , - * / |
分 | 0-59 | , - * / |
小时 | 0-23 | , - * / |
日期 | 1-31 | , - * / ? L W C |
月份 | 1-12 或 JAN-DEC | , - * / |
星期 | 1-7 或 SUN-SAT | , - * / ? L C # |
年(可选) | 留空 或 1970-2099 | , - * / |
特殊字符:
, 列出枚举值
- 区间
* 通配
/ 起始时触发后,隔固定时间触发一次
L 最后
W 有效工作日(周一到周五)
LW 连用 每月最后一个星期五
# 确定每个月的第几个星期几