事务的基本概念(理论)

一、事务是什么

百度百科:Java的事务处理,如果对数据库进行多次操作,每一次的执行或步骤都是一个事务。如果数据库操作在某一步没有执行或出现异常而导致事务失败,这样有的事务被执行有的就没有被执行,从而就有了事务的回滚,取消先前的操作。

二、事务的ACIP特点

(1)Atomic:原子性,操作要么一起成功,要么一起失败。

(2)Consistency:一致性,数据必须是准确的,执行前数据必须是准确的,执行后数据也必须是准确的。

(3)Isolation:隔离性,多个事务在跑的时候互不干扰

(4)Durability:持久性,事务成功了,就必须对数据的修改是永久有效的。

三、事务的隔离级别

(1)读未提交,read uncommitted:某个事务还未提交时,修改的数据让另一个事务读取捕获,也叫脏读。

(2)读已提交,read committed:事务A在跑的时候,查询一个数据为1,过段时间,事务B把数据修改成了2,并且提交成功了;此时事务A再次查询该数据变为了2,这是读了别人事务提交的数据,所以是读已提交。也叫不可重复读,就是所谓一个事务内对一个数据查询2次,可能会读到不同的结果。

(3)可重复读read repeatable:事务A在执行过程中,不管读几次某个数据C,读出来的数据C的值都是不变的,哪怕这个过程中事务B修改了该数据C并且提交了,事务A读到的还是自己事务开始时的这个数据的值。

(4)串行幻:事务A查询表里只有1行数据,事务B想插入数据B,但是事务A没执行完毕时,事务B被禁止执行,只有事务A执行提交后,事务B才能执行。解决幻读

(5)幻读(插入数据)不是隔离级别:在事务A读到一条数据C的时候,事务B插入并提交一条数据D到数据库。事务A查询第二次,查询到了2条数据。

四、事务的传播行为

事务的传播行为,默认值为 Propagation.REQUIRED。可以手动指定其他的事务传播行为。
(1)Propagation.REQUIRED:如果方法A当前存在事务,则方法B加入到该事务中,只要2个方法中,存在一个方法失败了,那么2个方法的事务全部都会回滚。如果方法A不存在事务,方法B会新起一个事务,方法B抛异常,方法B会回滚,方法A不会回滚。

(2)Propagation.SUPPORTS:如果方法A当前存在事务,则方法B加入该事务;如果方法A当前不存在事务,则方法B以非事务的方式继续运行。

(3)Propagation.MANDATORY:如果方法A当前存在事务,则方法B加入该事务;如果方法A当前不存在事务,则抛出异常。

(4)Propagation.REQUIRES_NEW:方法B强制创建一个新的事务,方法A的事务会卡住,等方法B事务执行完方法A才继续。如果方法A报错,方法B不受影响;如果方法B报错,往外抛异常,方法A捕获异常后可以选择回滚或者提交,如果方法A没有捕获异常会导致方法A回滚。

(5)Propagation.NOT_SUPPORTED:方法A暂停当前事务,方法B以非事务的方式运行结束,方法A继续。方法B(非事务)报错不会导致方法A回滚。

(6)Propagation.NEVER:方法B以非事务的方式运行,如果方法A存在事务进行调用,则方法B抛出异常。

(7)Propagation.NESTED:开启嵌套事务,方法B开启一个子事务,如果回滚,那么方法B就回滚到开启子事务的保存点(save point)。

五、项目里基于Spring的事务是如何设置

1、spring支持2种事务,编程事务和声明式事务。
(1)编程事务是使用TransationTemplate来管理事务
(2)声明式事务是在xml里配置个AOP来声明切面加个事务或者@Transaction注解。

2、现在一般是使用@Transactional来注解,根据阿里的规范,一般建议加在方法级。另外一般配合rollbackFor使用,指定哪些异常类才回滚事务。
(1)isolation属性可以设置事务的隔离级别,一般不建议调整
(2)propagation属性,事务的传播行为。

六、一个小例子

问题:前面50次成功,第51次失败。要求a,全部回滚;b前面50次提交,第51次回滚?

1、a要求:方法A跟方法B全部使用默认的@Transational
2、b要求:方法C使用默认的@Transational,方法B使用@Transatioanal(propagation=PROPAGATION.REQUIRES_NEW)

public void ServiceA{
	@autowrited
	private ServiceB b;
	//要求A
	@Transational
	public void functionA(){
		for(i=0;i<50;i++){
			b.functionB();
		}
	}
	//要求B
	@Transatioanal
	public void functionC(){
		for(i=0;i<50;i++){
			try{
				b.functionB();
			}catch(Exception e){
				//打印错误日志
			}
		}
	}
}
public void ServiceB{
	//A要求,方法A调用加:@Transational
	//B要求,方法C调用加:@Transatioanal(propagation=PROPAGATION.REQUIRES_NEW)
	public void funtionB(){
		//方法
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值