首先说一下,为什么需要事务。不是银行的那个例子哈哈。
最近刚开发一个审批功能,请假审批,第一步是填写请假数据。然后点击“申请请假”按钮启动审批。
启动审批的时候需要做两件事情
1.修改请假那条数据的审批状态(请假表里的 state 字段)。
2.启动流程,开始走审批(数据库中生成审批信息)。
因为在开发阶段,所以出现错误比较频繁。所以每次启动流程的时候报错,导致启动失败。但是状态已经修改。
所以需要去数据库删除那条数据或者把审批状态修改回来。很麻烦。
开始想的是把修改状态放在启动流程后面,因为修改状态这条sql出错的可能性很小。
但是,在项目运行中总会出现各种错误,可能导致修改状态时出错。用户就会把一条数据审批两次。
所以最好的方法就是让这两个操作一起成功或者一起失败。
所以就想到运用事务。
Spring的事务配置起来还是比较简单(这说注解式)。
在Spring配置文件中加入以下代码就可以用了。
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
其中dataSource是你配置的数据源。
然后可以使用@Transactional注解放到service方法上,这样就保证方法内的sql语句同时成功
@Transactional
public String startProcess(String classname, Integ
还有人觉得使用注解都闲麻烦的话,可以‘’百度spring aop 声明式事务‘’
啰嗦一下,说一下事务的四个特性。
1.原子性,编程方面的‘’原子‘’意思就是不可再分。要么全部成功,要么全部失败。
2.一致性,银行例子出现了。A转给B 500元,A-500 , B必须+500。
3.隔离性,事务的执行不受其它事务的干扰。
4.持久性,对于已经提交的数据,必须保证事务对数据库的改变不丢失。
再啰嗦一下,以上说的“隔离性”,具体怎样隔离是可以自己设置的(隔离级别)。不同的级别可能有不同的问题。
1.脏读。读到另一个事务中改写但还未提交的数据。
2.不可重复读。读到另一个事务中已经提交的修改。导致值不同。
3.幻读。读到另一个事务中已经提交的新增或者删除。导致记录数不同。
具体哪些级别就不说了。只说,Mysql默认的隔离级别。不会出现 1和2 的问题。可能出现 3