简单介绍一下事务
也不去系统的说概念了,以自己理解的为主
就是多个操作打包成为一个事务,成为原子性的操作
总结
要么都成功,要么都失败
再举一个例子
我去ATM机 用自己卡里的钱 给别人的卡 转账
转账之后 我的银行卡里钱减少,对方的银行卡前增加,这是正常的,这是一个业务,且必须保证原子性
来个反例
转账的时候,点击转账,突然中间过程卡了一下出现异常了,我在去查看,发现我的钱减少了,对方的钱没变,中间的过程出现异常没有执行对方账户前增加的操作,这样银行就乱套了。
spring 的环境jar包
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.18</version>
</dependency>
spring-tx 事务的jar包
<!-- https://mvnrepository.com/artifact/org.springframework/spring-tx -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.3.21</version>
</dependency>
spring-jdbc 操作数据库的jar包
<!-- Spring连接数据库的话需要jdbc-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.13</version>
</dependency>
mysql驱动包
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>
mybatis 的jar包
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.6</version>
</dependency>
mybtais-spring 的jar包
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.7</version>
</dependency>
spring-sonfig 文件中加入各种xml约束
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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
https://www.springframework.org/schema/tx/spring-tx.xsd ">
<!-- 数据源一般是固定代码-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 完全替代了配置文件-->
<property name="dataSource" ref="dataSource" />
<property name="mapperLocations" value="classpath:com/bit/mapper/UserMapper.xml"/>
</bean>
<bean id="userMapperImpl" class="com.bit.mapper.UserMapperImpl" >
<!-- 实现类的父类daoSupport需要注入sqlSessionFactory,然后daoSupport的作用就和SqlSession差不多,不需要sqlSession注入以及装配了-->
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
<!--开启aop注解的支持 -->
<aop:aspectj-autoproxy />
<!--在aop:config 中配置切面、切点、以及各种通知 或者使用注解配置即可-->
<!-- 开启组件注解支持-->
<context:annotation-config/>
<!-- 开启包路径注解扫描-->
<context:component-scan base-package="com.*"/>
</beans>
(1)首先在spring的核心配置文件中加入 DataSourceTransactionManage 对象
数据源和SqlSession什么的都得提前搞好!
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<constructor-arg ref="dataSource" />
</bean>
(2)定义事务的各种通知(应用的方法名字,通知的传播级别),使用aop将通知应用在切入点对应的方法中
<!-- 定义事务的各种通知,传播特性,应用的方法名字-->
<tx:advice id="txAdvice" transaction-manager="DataSourceTransactionManage">
<tx:attributes>
<tx:method name="method" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<!--在aop:config 中配置切面、切点、以及各种通知 或者使用注解配置即可-->
<aop:config>
<aop:pointcut id="pointcut" expression="execution(* com.bit.mapper.UserMapperImpl.method(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut"/>
</aop:config>
propagation 代表传播级别
事务的传播级别我们在后面还会用到,暂时不会那么深入,只需要用Required即可,如果存在一个事务,则支持当前事务。
如果是查找的方法,可以将read-only 属性设置为true,不允许支持修改操作,只支持读的操作
(3)在使用方法的时候,那么如果方法中又多个修改数据库的操作,那么要么都成功,要么都失败(一个失败事务回滚所有操作全部取消)
(1)加入事务注解开发的支持
<tx:annotation-driven transaction-manager="DataSourceTransactionManage" />
(2)直接在需要事务的方法上面加上 @Transactional即可,同时定义事务的各种属性
集成了spring环境、aop支持、事务支持、spring数据源、事务管理器、各种注解支持、各种组件扫描等等
有很多内容可以使用注解替代。。。
xml约束全部补齐
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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
https://www.springframework.org/schema/tx/spring-tx.xsd ">
<!-- 数据源一般是固定代码-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 完全替代了配置文件-->
<property name="dataSource" ref="dataSource" />
<property name="mapperLocations" value="classpath:com/bit/mapper/UserMapper.xml"/>
</bean>
<bean id="userMapperImpl" class="com.bit.mapper.UserMapperImpl" >
<!-- 实现类的父类daoSupport需要注入sqlSessionFactory,然后daoSupport的作用就和SqlSession差不多,不需要sqlSession注入以及装配了-->
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
<!-- 配置事务管理器,使用spring提供的-->
<bean id="DataSourceTransactionManage" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 定义事务的各种通知,传播特性,应用的方法名字-->
<tx:advice id="txAdvice" transaction-manager="DataSourceTransactionManage">
<tx:attributes>
<tx:method name="method" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<!--在aop:config 中配置切面、切点、以及各种通知 或者使用注解配置即可-->
<aop:config>
<aop:pointcut id="pointcut" expression="execution(* com.bit.mapper.UserMapperImpl.method(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut"/>
</aop:config>
<!--开启aop注解的支持 -->
<aop:aspectj-autoproxy />
<!-- 加入事务注解开发的支持-->
<tx:annotation-driven transaction-manager="DataSourceTransactionManage" />
<!-- 开启组件注解支持-->
<context:annotation-config/>
<!-- 开启包路径注解扫描-->
<context:component-scan base-package="com.*"/>
</beans>