什么是事务?
它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位。它保证了用户的每一次操作都是可靠的,即便出现了异常的访问情况,也不至于破坏后台数据的完整性
事务的特性
一个事务是有下列属性的一个工作单元:
原子性(ATOMICITY):
一个事务要被完全的无二义性的做完或撤消。在任何操作出现一个错误的情况下,构成事务的所有操作的效果必须被撤消,数据应被回滚到以前的状态。
一致性(CONSISTENCY):
一个事务应该保护所有定义在数据上的不变的属性(例如完整性约束)。在完成了一个成功的事务时,数据应处于一致的状态。换句话说,一个事务应该把系统从一个一致-状态转换到另一个一致状态。举个例子,在关系数据库的情况下,一个一致的事务将保护定义在数据上的所有完整性约束。
隔离性(ISOLATION):
在同一个环境中可能有多个事务并发执行,而每个事务都应表现为独立执行。串行的执行一系列事务的效果应该同于并发的执行它们。这要求两件事:
在一个事务执行过程中,数据的中间的(可能不一致)状态不应该被暴露给所有的其他事务。
两个并发的事务应该不能操作同一项数据。数据库管理系统通常使用锁来实现这个特征。
持久性(DURABILITY):
一个被完成的事务的效果应该是持久的。
Spring的事务管理
分类
- 编程式事务管理
- 声明式事务管理(常用)
- 基于xml配置文件实现
- 基于注解实现
api
Spring针对不同的dao层都提供了不同的实现类
转账环境
配置事务管理器
- 创建service和dao类,完成注入关系
- service业务逻辑层
- dao层,单独对数据库操作,在dao层不添加业务
<!-- 配置c3p0连接池 --> <!-- 创建对象 --> <bean id ="dataSource" class ="com.mchange.v2.c3p0.ComboPooledDataSource"> <!-- 注入属性值 --> <property name="driverClass" value="com.mysql.jdbc.Driver"></property> <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/testspring"></property> <property name="user" value="root"></property> <property name="password" value=""></property> </bean> <bean id="ordersService" class="com.ljy.service.OrdersService"> <property name="ordersDao" ref="ordersDao"></property> </bean> <bean id="ordersDao" class="com.ljy.dao.OrdersDao"> <property name="jdbcTemplate" ref="jdbcTemplate"></property> </bean> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> <!-- 源代码中有dataSource --> </bean>
- 需求:lucy给lily转账1000
未加事务
dao:
public class OrdersDao {
private JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
//少钱的方法
public void lessMoney(){
String sql = "update account set salary=salary-? where username=?";
jdbcTemplate.update(sql,1000,"lucy");
}
//多钱的方法
public void moreMoney(){
String sql = "update account set salary=salary+? where username=?";
jdbcTemplate.update(sql,1000,"lily");
}
}
service:
public class OrdersDao {
private JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
//少钱的方法
public void lessMoney(){
String sql = "update account set salary=salary-? where username=?";
jdbcTemplate.update(sql,1000,"lucy");
}
//多钱的方法
public void moreMoney(){
String sql = "update account set salary=salary+? where username=?";
jdbcTemplate.update(sql,1000,"lily");
}
}
如果lucy少了1000后出现了异常 程序不会继续执行 lily也不会多1000 。
解决方法
添加事务解决,出现异常时回滚操作
-
声明式事务管理(xml配置)
配置事务管理器
配置事物的增强<!-- 配置事务管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <!-- 注入datasource 表明对哪个数据库进行操作 --> <property name="dataSource" ref="dataSource"></property> </bean>
配置切面<!-- 配置事物的增强 --> <tx:advice id="txadvice" transaction-manager="transactionManager"> <!-- 做事务操作 --> <tx:attributes> <!-- 设置进行实务操作的方法匹配规则 --> <tx:method name="account*" propagation="REQUIRED"/> <!-- 以account开头的所有方法都可以执行这个事务 --> </tx:attributes> </tx:advice>
<!-- 配置切面产生代理 --> <aop:config> <!-- 切入点 --> <aop:pointcut expression="execution(* com.ljy.Service.*(..)" id="pointcut1"/> <!-- 切面 --> <aop:advisor advice-ref="txadvice" pointcut-ref="pointcut1"></aop:aspect> </aop:config>
-
声明式事务管理(注解)
配置事务管理器
配置事务注解
在要是用事务的方法所有类上面添加注解<tx:annotation-driven transaction-manager="transactionManager"/>
@Transactional public class OrdersService{
事务做了回滚后 数据库的数据不会有更改