什么是事务:简单来说,一个操作遵循原子性,隔离性,持久性,一致性四大事务特性的操作就是事务;
原子性:一个事务必须视为一个不可分割的最小工作单元,整个事务中的所有操作要么全部提交成功,要么全部失败回滚,对于一个事务来说,不可能只执行其中的一部分操作,这就是事务的原子性;
隔离性:一个事务所做的修改在最终提交以前,对其他事务是不可见的;
持久性:一旦事务提交,则其所做的修改就会永久保存到数据库中;
一致性:数据库总数从一个一致性的状态转换到另一个一致性的状态;
spring事务的隔离级别:
【1】DEFAULT(spring默认的隔离级别);
【2】READ_UNCOMMITTED (可以读未提交的数据);
【3】READ_COMMITTED(读已提交,oracle默认的级别),可以解决脏读;
【4】REPEATABLE_READ (MYSQL默认的级别) 可以解决脏读,不可重复读;
【5】SERALIZABLE (以下三种问题都可以解决,但是这是串行的,效率很低);
脏读:一个事务读取了另一个事务改写但是未提交的数据,如果这些数据被回滚,那么读到的数据就是无效的;
不可重复读:在同一个事务中,多次读取的返回的结果不一致;
幻读:一个事务读取了几行记录后,另一个事务插入一些记录,幻读就发生了,在后来的查询中,第一个事务就会发现有一些原来没有的记录。
spring事务的传播行为:
1、PROPAGATION_REQUIRED:支持当前事务,如果不存在就新建一个事务(默认);
2、PROPAGATION_SUPPORTS:支持当前事务,如果不存在,就不使用事务;
3、PROPAGATION_MANDATORY:支持当前事务,如果不存在,就抛出异常;
4、PROPAGATION_REQUIRES_NEW:如果有事务存在,挂起当前事务,创建一个新的事务;
5、PROPAGATION_NOT_SUPPORTED:以非事务方式运行,如果有事务存在,挂起当前事务;
6、PROPAGATION_NEVER:以非事务方式运行,如果有事务存在,抛出异常
7、PROPAGATION_NESTED:如果当前事务存在,则嵌套事务;
看了上面的基本概念,可能还是会比较模糊。接下来我们举个例子:(大家可以自己去链接数据库实际操作)
新建一个类A,其中有一个add方法,添加一个事务;
class A{
@transactional
public void add(int i){
}
}
新建一个类B,新建一个,添加一个事务;
class B{
@transactional
public void minus(int i){
}
}
新建一个测试类
class Test{
/**
*就相当于单独运行两个类里面的两个方法,那么这两个事务都可以成功的,
**/
@Test
public void test1(){
new A().add(1);
new B().minus(1);
}
/**
*我把B类的方法改一下:
class B{
@transactional
public void minus(int i){
new A().add(i);
}
}
*
*我们知道此时两个类中的两个方法都是有事务的,那么如果运行B方法会产生几个事务呢?此时这两个方法是在一个事务中执行的,因为spring默认新建事务的方式是,有就支持当前事务,没有就新建一个事务执行。
**/
@Test
public void test2(){
new B().minus(1);
}
}
在B类的方法中抛出一个异常,并对异常进行一下的操作(对事务的异常是否进行处理,什么时候处理,更改事务的传播方式),最后总结的请看下图:
相信通过上面的解释大家都有了一个新的理解。如果有什么想说的欢迎留言,大家一起探讨学习,共同进步,谢谢大家。