TransactionDefiniton中的5个事务隔离级别属性:
ISOLATION_DEFAULT:spring中默认的隔离级别;
ISOLATION_READ_UNCOMMITED:一个事务可以读到另一个事务中未提交的数据,可能出现脏读、不可重复读、幻像读等问题;
ISOLATION_READ_COMMITED:一个事务提交后,数据才能被其它事务读,避免了脏读,但会出现不可重复读和幻像读;
ISOLATION_REPEATABLE_READ:避免了脏读和不可重复读,会出现幻像读;
在事务1中,Mary 读取了自己的工资为1000,操作并没有完成
- con1 = getConnection();
- select salary from employee empId ="Mary";
在事务2中,这时财务人员修改了Mary的工资为2000,并提交了事务.
- con2 = getConnection();
- update employee set salary = 2000;
- con2.commit();
在事务1中,Mary 再次读取自己的工资时,工资变为了2000
- //con1
- select salary from employee empId ="Mary";
在一个事务中前后两次读取的结果并不致,导致了不可重复读。
使用ISOLATION_REPEATABLE_READ可以避免这种情况发生。
ISOLATION_SERIALIZABLE:隔离的最高级别,但消耗也很高。避免了脏读、不可重复读、幻像读。
幻像读:
目前工资为1000的员工有10人。
事务1,读取所有工资为1000的员工。
- con1 = getConnection();
- Select * from employee where salary =1000;
这时另一个事务向employee表插入了一条员工记录,工资也为1000
- con2 = getConnection();
- Insert into employee(empId,salary) values("Lili",1000);
- con2.commit();
事务1再次读取所有工资为1000的员工
- //con1
- select * from employee where salary =1000;
共读取到了11条记录,这就产生了幻像读。
ISOLATION_SERIALIZABLE能避免这样的情况发生。但是这样也耗费了最大的资源。
getPropagationBehavior()返回事务的传播行为,由是否有一个活动的事务来决定一个事务调用。
TRANSACTION中的7个事务传播行为:
PROPAGATION_REQUIRED:存在一个事务,则支持当前事务,不存在则新建一个事务;
PROPAGATION_SUPPORTS:存在一个事务,则支持当前事务,不存在则以非事务的方式执行;
PROPAGATION_REQUIRES_NEW:总是以新事务的方式执行,如果存在当前事务,则挂起;
PROPAGATION_NOT_SUPPORED:总是以非事务的方式运行,如果存在一个事务,则挂起;
PROPAGATION_MANDATORY:支持当前事务,如果不存在则抛出异常;
PAOPAGETION_NEVER:总是以非事务的方式执行,如果存在一个事务,则抛出异常;
PROPAGATION_NESTED:嵌套事务,内部事务依赖于外部事务,如果外部事务失败,则回滚外部、内部事务的所有操作,内部事务失败、则不影响外部事务的提交。如果没有当前事务,则以PROPAGATION_REQUIRED方式执行。