事务的四个关键属性(ACID)
原子性(atomicity): 事务是一个原子操作, 由一系列动作组成. 事务的原子性确保动作要么全部完成要么完全不起作用.
一致性(consistency): 一旦所有事务动作完成, 事务就被提交. 数据和资源就处于一种满足业务规则的一致性状态中.
隔离性(isolation): 可能有许多事务会同时处理相同的数据, 因此每个事物都应该与其他事务隔离开来, 防止数据损坏.
持久性(durability): 一旦事务完成, 无论发生什么系统错误, 它的结果都不应该受到影响. 通常情况下, 事务的结果被写到持久化存储器中.
数据库引擎InnoDB才支持事务,其他引擎均不支持
propagation事务的传播方式有7种
常用的有REQUIRED如果当前方法有事务在运行,那么就再当前事务中运行,
如果没有就创建新的事务运行
REQUIRED_NEW 当前的方法必须启动新事物,并在他自己的事物中运行,
如果当前方法有事务在运行,那么将此事务挂起
Spring事务传播方式/和数据库没有关系,和spring有关系 原因事务传播时service可能调用service方法
-----------------------------------------------------------------------------------------------------
高并发事务所导致的问题/···隔离级别
当同一个应用程序或者不同应用程序中的多个事务在同一个数据集上并发执行时, 可能会出现许多意外的问题
并发事务所导致的问题可以分为下面三种类型:
默认避免脏读
脏读: 对于两个事物 T1, T2, T1 读取了已经被 T2 更新但 还没有被提交的字段. 之后, 若 T2 回滚,
T1读取的内容就是临时且无效的.READ_COMMITED可避免脏读但是以下两种还是会出现
REPEATABLE_READ/锁行
不可重复读:对于两个事物 T1, T2, T1 读取了一个字段, 然后 T2 更新了该字段. 之后, T1再次读取
同一个字段, 值就不同了.解决方法/锁行
SERIALIZABLE /锁表
幻读:对于两个事物 T1, T2, T1 从一个表中读取了一个字段, 然后 T2 在该表中插入了一些新的行.
之后, 如果 T1 再次读取同一个表, 就会多出几行./解决锁表
配置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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:cache="http://www.springframework.org/schema/cache"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache-3.1.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd"
default-lazy-init="true">
<!--扫描全局-->
<context:component-scan base-package="com.lovo.stopcar.*"></context:component-scan>
<context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
<!-- 配置jdbc 数据库的连接地址及账号密码 -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="url" value="${jdbc_url}"></property>
<property name="driverClassName" value="${jdbc_driver}"></property>
<property name="username" value="${jdbc_user}"></property>
<property name="password" value="${jdbc_password}"></property>
</bean>
<!-- mybaitis的工厂-->
<bean id="factoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
<!--获取数据源连接数据库的配置文件id-->
<property name="dataSource" ref="dataSource"></property>
<!--为所有的bean类取别名 便于查找-->
<property name="typeAliasesPackage" value="com.lovo.stopcar.Bean"></property>
<!--绑定sql语句的配置文件-->
<property name="mapperLocations" value="classpath:com/lovo/stopcar/Dao/*.xml"></property>
</bean>
<!--用mapped对象绑定我们写的接口 -->
<!--basePackage:这个属性就是映射接口的包,这个包里面的所有的接口扫描到-->
<!--sqlSessionFactory:这个属性要注意他不是让我们去配置的,他是为了通过自动装配的属性,而不需要我们去配置这个属性-->
<!--sqlSessionFactoryBeanName:为了将我们的sqlSessionFactory注入给它这个类 -->
<!--annotationClass:自定义一个注解加大排除我们所需要的Mapper接口,-->
<!--(ps:首先我们扫描这个包可能有不需要映射的接口,那我们就可以通过注解(自定义的注解)的方式选出我们所需要的,没加注解的就不是这个类所需要的)-->
<bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--获取mybatis的工厂配置 这里获取的是String 所以用 value来获取mybatis工厂配置的id -->
<property name="sqlSessionFactoryBeanName" value="factoryBean"></property>
<!--basePackage:这个属性就是映射接口的包,这个包里面的所有的接口扫描到-->
<property name="basePackage" value="com.lovo.stopcar.Dao"></property>
</bean>
<!-- 事务管理器 Spring-jdbc -dataSourceTransactionManager 事务管理器连接到collection-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 事务通知 -->
<tx:advice id="myadvice" transaction-manager="transactionManager">
<tx:attributes>
<!--name调用事务的方法,rollback-for当出现Excption(也可具体到某种异常)异常的时候 propagation="REQUIRED"事务的传播方式 默认REQUIRED-->
<tx:method name="mains" propagation="REQUIRED" rollback-for="Excption"></tx:method>
<tx:method name="outCar" propagation="REQUIRED" rollback-for="Excption"></tx:method>
</tx:attributes>
</tx:advice>
<!-- aop通知 -->
<aop:config>
<!--aop增强通知 把外部通知连接 外部通知来自事务管理器-->
<!--myadvice 事务通知 name="mains" 的方法来自 pointcut="execution(* com.lovo.shop.service.*.*(..))此路径下的方法事务-->
<aop:advisor advice-ref="myadvice" pointcut="execution(* com.lovo.stopcar.Service.*.*(..))"></aop:advisor>
</aop:config>
</beans>