1.了解事物的概念及其特性
数据库事务(DataBase Transaction)是指作为单个逻辑工作单元执行的一系列操作,要么完全的执行,要么完全的不执行。
事务的特点:
1.原子性:指事务是一个不可分割的工作单位 ,事务中操作要么都发生,要么都不发生
2.一致性:指的是事务前后数据的完整性必须保持一致
3.隔离性:指多个用户并发访问数据库时,一个用户的事务不能被其他用户的事务所干扰,多个并发事务之间数据要相互隔离。
4.持久性: 指一个事务一旦提交,它对数据库中的数据的改变是永久性,即时数据库发生故障不应该对它有影响
2.了解Spring对事物的两种支持方式,掌握声明式事务管理
spring对于事务的管理分为两种:
编程式事务
通过编写代码来管理事务,类似于jdbc里面的通过代码来对事务进行提交或者回滚。
优点:事务最细力度可以做到代码块级别。
缺点:会污染业务代码。
声明式事务
通过使用xml配置文件或者注解的方式来管理事务,无需编写代码,原理是使用aop进行事务的管理。
优点:不会污染业务代码,通过配置文件或注解即可完成事务的管理
缺点:事务最细力度只能做到方法级别。
<!--配置事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="c3p0"/>
</bean>
<!--
配置的形式实现事务
-->
<!--配置事务处理-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!--name: service中要进行事物添加的方法名,可用通配符*
propagation: 事物的传播行为
isolation:事务隔离级别定义;默认为“DEFAULT” -->
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
<!-- (3)配置AOP让事务生效-->
<aop:config>
<aop:pointcut id="point" expression="execution(* cn.gok.Services.UserServise.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="point"/>
</aop:config>
service
public interface UserServise {
// 添加用户
public boolean addUser(User user);
// 查询所有用户信息
public List<User> getUsers();
// 用户转账(用户id、对方id、转账金额)
public boolean sendMoney(String userId,String otherId,Double money);
}
serviceImpl
@Transactional(noRollbackFor = {ArithmeticException.class})//事务注解 noRollbackFor:遇到该异常不做回滚
@Override
public boolean sendMoney(String userId, String otherId, Double money) {
/*
* 获得用户的账户信息
* 用户1转给用户2
* */
User u1=userDao.getById(userId);//用户1的账户信息
User u2 = userDao.getById(otherId);//用户2的账户信息
/*
* 金钱的更改
* */
//设置用户1的金钱为 用户1之前的金钱减去转账的金钱
u1.setMoney(u1.getMoney()-money);
//设置用户2的金钱为之前的金钱+转过来的金钱
u2.setMoney(u2.getMoney()+money);
/*
* 调用插入方法把他们各自的金钱更新回去
* */
int out1=userDao.changeUser(u1);
/*
* 模拟程序错误
* */
// int a=10/0;
int out2=userDao.changeUser(u2);
/*
* 两个人都有更新才返回成功
* */
if (out1>0&out2>0){
return true;
}
return false;
}
3.掌握了解事物的并发问题和事物传播
@Transactional中的属性如下:
propagation :用于设置事务传播属性。该属性类型为 Propagation 枚举,默认值为Propagation.REQUIRED。
isolation : 用于设置事务的隔离级别。该属性类型为 Isolation 枚举,默认值为Isolation.DEFAULT。
readOnly:用于设置该方法对数据库的操作是否是只读的。该属性为 boolean,默认值为 false。
timeout:用于设置本操作与数据库连接的超时时限。单位为秒,类型为 int,默认值为-1,即没有时限。
rollbackFor:指定需要回滚的异常类。类型为 Class[],默认值为空数组。当然,若只有一个异常类时,可以不使用数组。
rollbackForClassName: 指定需要回滚的异常类类名。类型为 String[],默认值为空数组。当然,若只有一个异常类时,可以不使用数组。
noRollbackFor:指定不需要回滚的异常类。类型为 Class[],默认值为空数组。当然,若只有一个异常类时,可以不使用数组。
noRollbackForClassName:指定不需要回滚的异常类类名。类型为 String[],默认值为空数组。当然,若只有一个异常类时,可以不使用数组。
并发问题:
Spring实现事务隔离
这些常量均是以 ISOLATION开头。例如 ISOLATIONREPEAT ABLE_READ。
DEFAULT:采用 DB 默认的事务隔离级别。MySql 的默认为 REPEATABLEREAD;Oracle默认为 READCOMMITTED。
READ_UNCOMMITTED:读未提交。未解决任何问题。
READ_COMMITTED:读已提交。解决脏读,存在不可重复读与幻读。
REPEATABLE_READ:可重复读。解决脏读、不可重复读,存在幻读
SERIALIZABLE:串行化。解决脏读、不可重复读,幻读的问题,效率低。
4.事物回滚
@Transaction默认情况下RuntimeException异常触发事务回滚