赞
踩
【Spring系列】IOC操作bean管理(一)——bean管理实例详解
【Spring系列】IOC操作bean管理(二)——bean的生命周期、作用域
【Spring系列】IOC操作bean管理(三)——xml自动装配
【Spring系列】IOC操作bean管理(四)——引入外部属性文件
【Spring系列】IOC操作bean管理(五)——bean管理注解
(1)事务是数据库操作最基本单元;
(2)事务指的是逻辑上一组操作,要么都成功,如果有任何一个失败,所有都失败;
(3)事务典型场景:银行转账;
(1)原子性: 不可分割,只有操作都成功
(2)一致性: 操作前后总量不变
(3)隔离性: 并发操作,多个事务之间不会产生影响
(4)持久性: 当事务结束之后,数据库真正发生变化
(1)脏读: 两个事务都没有提交,但是都能看到对方事务的操作(致命问题);
(2)不可重复读: 一个事物提交了,另一个事务没有提交,但没有提交的这个事务能看到这个已经提交事务的操作(现象);
(3)幻(虚)读: 一个事务提交了,另一个事务没有提交,但没有提交的这个事务能看到这个已经提交事务的 添加 操作(现象);
(1)设置事务隔离级别
隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
Read Uncommitted(读未提交) | 有 | 有 | 有 |
ReadCommitted(读已提交) | 无 | 有 | 有 |
Repeatable Read(可重复读) | 无 | 无 | 有 |
Serializable(串行化/不可并发) | 无 | 无 | 无 |
(2)mysql默认隔离级别:repeatable read
下面讲解一个转账的实例,来演示事务的配置过程
表结构:
表数据:
dao类:
package com.springlearn.dao;
public interface UserDao {
//转账——少钱的方法
public void decrMoney();
//转账—多钱的方法
public void incrMoney();
}
service类:
package com.springlearn.service;
import com.springlearn.dao.UserDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @program: SpringTX
* @description:
* @author: txg
* @create: 2021-08-27 11:04
**/
@Service
public class UserService {
@Autowired
private UserDao userDao;
//转账的方法
public void accountMoney(){
//调用少钱的方法
userDao.decrMoney();
//调用多钱的方法
userDao.incrMoney();
}
}
dao的实现类:
package com.springlearn.dao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
/**
* @program: SpringTX
* @description:
* @author: txg
* @create: 2021-08-27 11:03
**/
@Repository
public class UserdaoImpl implements UserDao{
@Autowired
private JdbcTemplate jdbcTemplate;
//转账——少钱的方法 Lucy少100
@Override
public void decrMoney() {
String sql="update account set money=money-? where username=?";
jdbcTemplate.update(sql,100,"lucy");
}
//转账——多钱的方法 mary多100
@Override
public void incrMoney() {
String sql="update account set money=money+? where username=?";
jdbcTemplate.update(sql,100,"mary");
}
}
package com.springlearn;
import com.springlearn.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @program: SpringTX
* @description:
* @author: txg
* @create: 2021-08-27 11:04
**/
public class Main {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
UserService userService = context.getBean("userService", UserService.class);
userService.accountMoney();
}
}
结果:
上面代码如果出现异常,会产生问题,我们可以使用事务解决
PlatformTransactionManager
JdbcTemplate
,会使用实现类 DataSourceTransactionManager
<!--配置事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--注入DataSource-->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--开启事务注解-->
<tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
@Transactional
;@Transactional
注解可以添加到service类上面,和添加service里的方法上面,注解所添加位置的区别如下表:位置 | 特点 |
---|---|
添加service类上面 | 类里面所有方法都添加了事务 |
如果只是添加到了方法上面 | 则只是添加注解的方法有事务 |
@Transactional
public class UserService {
… …
}
(1)timeout
:事务提交时间设置
(2)readonly
:是否只读
(3)rollBackFor
:回滚
(4)noRollBackFor
:不回滚
(5)isolation
:设置事务隔离级别 (☆)
repeatable read
(6)propagation
:设置事务传播行为 (☆)
概念: 多事务方法之间调用过程中,事务是如何使用的
事务方法: 改变数据库表数据的方法,添加修改删除
例如: 添加方法里面调用修改方法,这个时候的事务如何使用,成为事务的传播行为
spring提供多种事务传播行为(七种)
第一种 REQUIRED
如果有事务,使用这个事务,如果没有事务,创建新事务
第二种 REQUIRED_NEW
都是创建新事务,如果之前有事务,不使用
第三种 SUPPORT
如果有事务,使用这个事务,如果没有事务,不使用事务
第四种 NOT_SUPPORT
不用事务
第五种 MANDATORY
如果有事务,使用这个事务,如果没有事务,就抛出异常
第六种 NEVER
如果没有事务,就正常运行,有事务就抛出异常
第七种 NESTED
如果有事务,就再嵌套一个事务在其中使用,如果没有事务,创建新事务
@Service
@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.REPEATABLE_READ)
public class UserService {
(1)个人所得税的例子
(2) spring事务管理配置中使用策略模式
spring事务管理使用顶层接口 PlatformTransactionManager
配置较为复杂,需要多配置三个内容。具体配置如下:
<?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:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop http://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.springlearn"></context:component-scan>
<!--配置德鲁伊连接池-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
<property name="url" value="jdbc:mysql:///tbl_test"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
</bean>
<!--配置事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--注入DataSource-->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--配置增强(通知)-->
<tx:advice id="txadvice">
<tx:attributes>
<!--配置对哪种规则的方法添加事务-->
<tx:method name="account*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<!--配置切入点和切面-->
<aop:config>
<!--切入点-->
<aop:pointcut id="p" expression="execution(* com.springlearn.service.UserService.*(..))"/>
<!--切面:把哪个增强用到哪个切入点-->
<aop:advisor advice-ref="txadvice" pointcut-ref="p"></aop:advisor>
</aop:config>
<!--创建jdbcTemplate对象-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<!--注入数据源属性-->
<property name="dataSource" ref="dataSource"></property>
</bean>
</beans>
使用配置类来代替xml配置文件:
@Bean
注解的作用
1:让方法执行
2:让方法返回在spring进行注册(因为spring是通过bean来创建对象的,new的对象识别不到,所以需要注册spring才能识别到)
package com.springlearn.config;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
/**
* @program: SpringTX
* @description:
* @author: txg
* @create: 2021-08-27 20:57
**/
@Configuration
@ComponentScan(basePackages = {"com.springlearn"}) //开启组件扫描
@EnableTransactionManagement //开启事务注解
public class SpringConfig {
//创建德鲁伊连接池
//@Bean作用
//1:让方法执行 2:让方法返回在spring进行注册
@Bean
public DruidDataSource getDruidDataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql:///test");
dataSource.setUsername("root");
dataSource.setPassword("123456");
return dataSource;
}
//创建JdbcTemplate对象
@Bean
public JdbcTemplate getJdbcTemplate(DataSource dataSource) {
//到ioc容器中根据类型找到dataSource
JdbcTemplate jdbcTemplate = new JdbcTemplate();
//注入dataSource
jdbcTemplate.setDataSource(dataSource);
return jdbcTemplate;
}
//创建事务管理器
@Bean
public DataSourceTransactionManager getDataSourceTransactionManager(DataSource dataSource) {
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
transactionManager.setDataSource(dataSource);
return transactionManager;
}
}
这篇文章对你有帮助嘛!
欢迎提出宝贵的建议!
感谢阅读~
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。